C# 异步UDP发送接收数据

UDP:User Datagram Protocol 用户数据报协议,是一个无连接的传输协议。
所以不像TCP一样要使用ConnectAsync来与服务器连接,直接向服务器发送数据即可。

参考:MSDN

public bool ReceiveFromAsync (System.Net.Sockets.SocketAsyncEventArgs e);

Returns
Boolean
true if the I/O operation is pending. The Completed event on the e parameter will be raised upon completion of the operation.

false if the I/O operation completed synchronously. In this case, The Completed event on the e parameter will not be raised and the e object passed as a parameter may be examined immediately after the method call returns to retrieve the result of the operation.

简单来说就是如果返回值是true就等待处理,接收成功了会触发回调事件
如果是false就说明已经同步处理完成了,这时回调事件不会触发,需要自己手动执行。
SendToAsync也是一个道理
也就有了下面的代码:

...省略定义一些成员变量:connectSocket,endPoint 等
...省略(构造函数,传入ip和port)...
        connectSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        IPAddress address;
        if (!IPAddress.TryParse(ip, out address)) // 尝试解析IP,万一它是一个域名呢
        {
            try
            {
                IPHostEntry host = Dns.GetHostEntry(ip);
                address = host.AddressList[0];
            }
            catch (Exception)
            {
            	Console.WriteLine("IP解析错误!");
            }
        }
        endPoint = new IPEndPoint(address, port);
...

...省略(定义一个“发消息”方法,传入byte[] buff)...
    SocketAsyncEventArgs saea = new SocketAsyncEventArgs();
    saea.SetBuffer(buff, 0, buff.Length);
    saea.UserToken = connectSocket;
    saea.Completed += new EventHandler<SocketAsyncEventArgs>(IO_Completed);
    saea.RemoteEndPoint = endPoint;
    if (!connectSocket.SendToAsync(saea))
    {
        IO_Completed(null, saea);
    }
...

private void IO_Completed(object sender, SocketAsyncEventArgs e)
{
    switch (e.LastOperation)
    {
        case SocketAsyncOperation.ReceiveFrom:
            ProcessReceive(e);
            break;
        case SocketAsyncOperation.SendTo:
            ProcessSend(e);
            break;
        default:
            Console.WriteLine(e.LastOperation);
            break;
    }
}
/// <summary>
/// 处理udp客户端发送的结果
/// </summary>
/// <param name="e"></param>
private void ProcessSend(SocketAsyncEventArgs e)
{
    if (e.SocketError == SocketError.Success)
    {
    	// 发送成功就可以准备接收
    	byte[] buff = new buff[1024]
	    SocketAsyncEventArgs saea = new SocketAsyncEventArgs();
	    saea.SetBuffer(buff, 0, buff.Length);
	    saea.UserToken = connectSocket;
	    saea.Completed += new EventHandler<SocketAsyncEventArgs>(IO_Completed);
	    saea.RemoteEndPoint = endPoint;
        if (!connectSocket.ReceiveFromAsync(saea))
            IO_Completed(null, saea);
    }
    else
    {
    	// 发送失败
    }
}
/// <summary>
/// 处理接受到的udp服务器数据
/// </summary>
/// <param name="e"></param>
private void ProcessReceive(SocketAsyncEventArgs e)
{
    if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
    {
    	//处理接收到的数据(e.Buffer);
    }
    else
    {
    	//没有接收到数据
    }
}
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值