.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
            
{
            }

        }

 

代碼是不是很簡單?功能是不是很強大?

發佈了51 篇原創文章 · 獲贊 4 · 訪問量 18萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章