首页  ·  知识 ·  编程语言
Net高效UDP异步编程
寒冬星空  http://www.cnblogs.com/wenanry/  .NET  编辑:dezai  图片来源:网络
因为要写一个网络程序要用到UDP协议,UDP这东西比较麻烦,又不像TCP一样提供可靠的连接,发送接收的超时实在不好设计,最后只要用Timer来检测有没有想要的数据包

因为要写一个网络程序要用到UDP协议,UDP这东西比较麻烦,又不像TCP一样提供可靠的连接,发送接收的超时实在不好设计,最后只要用Timer来检测有没有想要的数据包-_#,不过这不是这次的重点,重点是怎么建立一种高效的UDP机制来实时接收服务器发送过来的数据包.
     CodeProject上有个例子是开个线程去同步接收,这样倒是可以满足我的程序需求,不过实际中遇到几个问题:

     1.程序开销大,内存狂飙,接一次数据就要重新开一次线程

     2.由于主界面和底层是完全隔离只是通过中间的接口来通讯,导致线程总是不能正常的结束,程序结束后还有一个进程在那里不知道干什么.

     于是翻阅MSDN,查找自己以前写的代码,最后还是决定用异步来接收,MSDN上UDP异步的例子不太好,有点敷衍的意思,用异步很好的解决了以上的问题,高效完成效率,代码如下:

 

UdpClient qq_client;    //Udp客户端
qq_client = new UdpClient();
IPEndPoint remoteQQEP = new IPEndPoint(remotehost, remoteport);
qq_client.Connect(remoteQQEP);


AsyncCallback GetRecvBuffer = new AsyncCallback(ReceiveCallback);
qq_client.BeginReceive(GetRecvBuffer, null);  
这里用一个GetRecvBuffer的回掉来实现异步

 

        private void ReceiveCallback(IAsyncResult ar)
        {
            try
            {
                lock (this)
                {
                    byte[] recvbytes = qq_client.EndReceive(ar, ref remoteQQEP);
                    //QQFunction.DebugDump(recvbytes);


                    if (recvbytes[0] != QQDef.QQ_IM_HEAD && recvbytes[0] != 0x03)
                    {
                        //非QQ数据包
                        return;
                    }
                    switch (Pop16(recvbytes, 3))
                    {
                        case QQDef.QQ_REQUEST_TOKEN:
                            DoGetToken(recvbytes);
                            break;
                        case QQDef.QQ_REQUEST_LOGIN:
                            DoGetLogin(recvbytes);
                            break;
                        case QQDef.QQ_GET_ONLINE_FRIEND:
                            DoGetOnline(recvbytes);
                            break;
                        case QQDef.QQ_KEEP_ALIVE:
                            CheckAlive(recvbytes);
                            break;
                        case QQDef.QQ_SEND_IM_MSG:
                            // Do SomeThing
                            break;
                        case QQDef.QQ_RECV_IM_MSG:
                            DoRecvMsg(recvbytes);
                            break;
                        default:
                            QQFunction.DebugDump("UnKnow Command");
                            QQFunction.DebugDump(recvbytes);
                            break;
                    }
                   
                }
                lock (this)
                {
                    AsyncCallback GetRecvBuffer = new AsyncCallback(ReceiveCallback);
                    qq_client.BeginReceive(GetRecvBuffer, null);
                }
            }
            catch
            {
            }
        }

 

代码是不是很简单?功能是不是很强大?

 

本文作者:寒冬星空 来源:http://www.cnblogs.com/wenanry/
CIO之家 www.ciozj.com 微信公众号:imciow
   
免责声明:本站转载此文章旨在分享信息,不代表对其内容的完全认同。文章来源已尽可能注明,若涉及版权问题,请及时与我们联系,我们将积极配合处理。同时,我们无法对文章内容的真实性、准确性及完整性进行完全保证,对于因文章内容而产生的任何后果,本账号不承担法律责任。转载仅出于传播目的,读者应自行对内容进行核实与判断。请谨慎参考文章信息,一切责任由读者自行承担。
延伸阅读