当前位置: 首页 > news >正文

Unity中UDP异步通信常用API使用

Begin开头的方法

BeginSendTo

BeginSendTo 是 UdpClient 类中的一个重要方法,用于开始一个异步操作来发送 UDP 数据报到指定的远程端点

public IAsyncResult BeginSendTo(
    byte[] datagram,
    int bytes,
    IPEndPoint endPoint,
    AsyncCallback requestCallback,
    object state
);

参数解释

  • datagram:要发送的字节数组,也就是你要发送的数据内容。
  • bytesdatagram 数组中要发送的字节数。
  • endPointIPEndPoint 类型,代表数据报要发送到的远程端点,包含了目标 IP 地址和端口号。
  • requestCallbackAsyncCallback 类型的回调方法,当异步发送操作完成时会调用这个方法。
  • state:一个用户定义的对象,它会被传递给回调方法,可用于在回调方法中携带额外的状态信息。

返回值

该方法返回一个 IAsyncResult 对象,可用于跟踪异步操作的状态。可以把这个对象传递给 EndSendTo 方法来完成异步操作。

BeginReceiveFrom

BeginReceiveFrom 是 UdpClient 类里的一个方法,用于开始一个异步操作,从指定的远程端点接收 UDP 数据报

public IAsyncResult BeginReceiveFrom(
    byte[] buffer,
    int offset,
    int size,
    ref EndPoint remoteEP,
    AsyncCallback requestCallback,
    object state
);

参数解释

  • buffer:用于接收数据的字节数组。
  • offset:在 buffer 中开始存储接收到的数据的偏移量。
  • sizebuffer 中可用于存储数据的最大字节数。
  • remoteEPEndPoint 类型的引用,代表发送数据报的远程端点。在接收操作完成后,该参数会被更新为实际发送数据的远程端点信息。
  • requestCallbackAsyncCallback 类型的回调方法,当异步接收操作完成时会调用此方法。
  • state:一个用户定义的对象,会被传递给回调方法,可用于在回调方法中携带额外的状态信息。

返回值

该方法返回一个 IAsyncResult 对象,可用于跟踪异步操作的状态。你可以把这个对象传递给 EndReceiveFrom 方法来完成异步操作。

Begin开头的方法要和End开头的方法配套使用

Async结尾的方法

SendToAsync

SendToAsync 是 UdpClient 类中用于异步发送 UDP 数据报到指定远程端点的方法,它是 .NET 中提供的基于任务的异步模式(TAP)的方法,相比于传统的 BeginSendTo 和 EndSendTo 组合,使用起来更加简洁和直观,结合 async 和 await 关键字能让代码更具可读性。

public Task<int> SendToAsync(byte[] datagram, int bytes, IPEndPoint endPoint);

参数解释

  • datagram:要发送的字节数组,即你要传输的数据内容。
  • bytesdatagram 数组中要发送的字节数。
  • endPointIPEndPoint 类型,代表数据报要发送到的远程端点,包含目标 IP 地址和端口号。

返回值

该方法返回一个 Task<int> 对象,Task 表示异步操作,int 表示实际发送的字节数。你可以使用 await 关键字等待这个任务完成,并获取发送的字节数。

ReceiveFromAsync

ReceiveFromAsync 是 UdpClient 类中的一个方法,它以异步方式从指定的远程端点接收 UDP 数据报。这个方法遵循基于任务的异步模式(TAP),借助 async 和 await 关键字,能够让代码的异步操作变得更加简洁和易读。

public Task<UdpReceiveResult> ReceiveFromAsync();

返回值

该方法返回一个 Task<UdpReceiveResult> 对象。Task 代表一个异步操作,而 UdpReceiveResult 是一个结构体,包含两个重要属性:

  • Buffer:一个字节数组,存储着接收到的数据。
  • RemoteEndPointEndPoint 类型,指示发送数据的远程端点。

方法使用

using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using UnityEngine;

public class Lesson16 : MonoBehaviour
{
    byte []cachebytes = new byte[512];
    // Start is called before the first frame update
    void Start()
    {
        #region UDP异步通信中begin相关的方法
        Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        //BeginSendTo
        byte[] bytes = Encoding.UTF8.GetBytes("w9r39hjfwaofi");
        EndPoint IpPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8080);
        socket.BeginSendTo(bytes, 0, bytes.Length, SocketFlags.None, IpPoint, SendOver, socket);
        //BeginReceiveFrom
        socket.BeginReceiveFrom(cachebytes, 0, cachebytes.Length, SocketFlags.None, ref IpPoint, ReceiveFromOver, (socket, IpPoint));
        #endregion
        #region UDP异步通信中Async结尾的方法
        //SendToAsync
        SocketAsyncEventArgs args = new SocketAsyncEventArgs();
        args.SetBuffer(bytes, 0, bytes.Length);
        args.Completed += SendAsync;
        socket.SendToAsync(args);
        //ReceiveFromAsync
        SocketAsyncEventArgs args2 = new SocketAsyncEventArgs();
        socket.ReceiveFromAsync(args2);
        args2.SetBuffer(cachebytes, 0, cachebytes.Length);
        args2.Completed += ReceiveAsync;
        #endregion 
    }
    private void SendOver(IAsyncResult result)
    {
        try
        {
            Socket s = result.AsyncState as Socket;
            s.EndSendTo(result);
        }
        catch (SocketException s)
        {
            print("发消息出问题了" + s.SocketErrorCode + s.Message);
        }
      
    }
    private void ReceiveFromOver(IAsyncResult result)
    {
        try
        {
            (Socket s, EndPoint ipPont) info = ((Socket ,EndPoint))result.AsyncState;
            //返回值 就是接收了多少个字节数
            int num=info.s.EndReceiveFrom(result, ref info.ipPont);
            //处理消息

            //处理完消息继续接收消息
            info.s.BeginReceiveFrom(cachebytes, 0, cachebytes.Length,SocketFlags.None,ref info.ipPont, ReceiveFromOver, info);
        }
        catch (SocketException s)
        {
            print("接收消息失败" + s.SocketErrorCode + s.Message);
        }
    }
    private void SendAsync(object s,SocketAsyncEventArgs args)
    {
        try
        {
            print("发消息成功");
        }
        catch (SocketException e)
        {
            print("发消息出问题了" + e.SocketErrorCode + e.Message);
        }
    }
    private void ReceiveAsync(object s,SocketAsyncEventArgs args)
    {
       if(args.SocketError ==SocketError.Success)
       {
            print("接收消息成功");
            //具体收了多少字节
            //args.BytesTransferred
            //可以通过以下两种方式获取收到的字节数组的内容
            //args.Buffer
            //cacheBytes
            //解析消息

            Socket socket = s as Socket;
            args.SetBuffer(0, cachebytes.Length);
            //只需要设置从第几个位置开始接 能接多少
            socket.ReceiveFromAsync(args);
       }    
       else
        {
            print("收消息失败");
        }
    }
    // Update is called once per frame
    void Update()
    {
        
    }
}

相关文章:

  • Python小练习系列 Vol.7:全排列生成(回溯算法模板题)
  • Spring笔记03-依赖注入
  • Javaweb后端登录认证 登录校验 过滤器 filter令牌校验,执行流程,拦截路径
  • 业之峰与宏图智能战略携手,开启家装数字化新篇章
  • excel 时间戳 转日期
  • shop搜索需求及测试点
  • 01-Docker 安装
  • 知识图谱之知识抽取:从数据海洋中 “捞金”
  • Plastiform复制胶泥:高精度表面复制与测量的高效工具
  • 如何学习Python编程?
  • Emacs 折腾日记(二十)——修改emacs的一些默认行为
  • 三层交换综合实验
  • 【Java SE】StringBuffer、StringBuilder详解
  • 【C++】C++11介绍列表初始化右值引用和移动语义
  • .js项目编译成.exe程序(交叉编译全过程整理)
  • 在 Ant Design Vue 中实现滚动页面时保持下拉菜单展开
  • Strawberry perl的下载,查询版本号,配置Path环境变量,查找perl解释器的位置
  • 淘宝API与小程序联动:实现“一键转卖”功能开发实战
  • 虚拟电商-话费充值业务(二)话费充值对接供应商模块开发
  • 从虚拟现实到可持续设计:唐婉歆的多维创新之旅
  • 讲座|为什么要不断地翻译叶芝的诗?它们为什么值得细读?
  • 国新办发布《关于新冠疫情防控与病毒溯源的中方行动和立场》白皮书
  • 摩根大通任命杜峯为亚太区副主席,加码中国市场业务布局
  • 屠呦呦当选美国科学院外籍院士
  • 外媒称菲方允许菲官员窜台,国台办:应停止在台湾问题上玩火
  • A股三大股指收跌:地产股领跌,银行股再度走强