[转].Net高效UDP异步编程

 因为要写一个网络程序要用到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
            
{
            }

        }


 

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

 


Trackback: http:
//tb.blog.csdn.net/TrackBack.aspx?PostId=1750678

原文地址:
http://blog.csdn.net/fsc2988877/archive/2007/08/19/1750678.aspx
posted @   wenanry  阅读(3806)  评论(1编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
历史上的今天:
2006-09-26 DataSet 的Cache功能
2006-09-26 如何下载sql server 2005中的northwind 和 pubs数据库
点击右上角即可分享
微信分享提示