2015-07-19 129 views
1

我一直在環顧四周,無法真正找到我需要的東西,特別是對於UDP。針對多個客戶端的C#.NET UDP套接字異步

我試圖做一個基本的系統日誌服務器偵聽端口514(UDP)。

我一直在關注微軟的MSDN上的指南:https://msdn.microsoft.com/en-us/library/system.net.sockets.udpclient.beginreceive(v=vs.110).aspx

它不明確狀態(或者我瞎了)如何重新打開更多的數據包的連接被收到。

這裏是我的代碼(也就是從鏈路都相同)

 static void Main(string[] args) 
    { 
     try 
     { 
      ReceiveMessages(); 

      Console.ReadLine(); 

     }catch(SocketException ex) 
     { 
      if(ex.SocketErrorCode.ToString() == "AddressAlreadyInUse") 
      { 
       MessageBox.Show("Port already in use!"); 
      } 
     } 

    } 

    public static void ReceiveMessages() 
    { 
     // Receive a message and write it to the console. 



     UdpState s = new UdpState(); 

     Console.WriteLine("listening for messages"); 
     s.u.BeginReceive(new AsyncCallback(ReceiveCallback), s); 
     RecieveMoreMessages(s); 
    } 

    public static void RecieveMoreMessages(UdpState s) 
    { 
     s.u.BeginReceive(new AsyncCallback(ReceiveCallback), s); 
    } 

    public static void ReceiveCallback(IAsyncResult ar) 
    { 
     UdpClient u = (UdpClient)((UdpState)(ar.AsyncState)).u; 
     IPEndPoint e = (IPEndPoint)((UdpState)(ar.AsyncState)).e; 

     Byte[] receiveBytes = u.EndReceive(ar, ref e); 
     string receiveString = Encoding.ASCII.GetString(receiveBytes); 

     Console.WriteLine("Received: {0}", receiveString); 
    } 

我試圖重申,但我後2個交易運行到「暗戰的緩衝空間」從插座中的錯誤。

任何想法?

回答

1

如果您堅持使用過時的APM模式,則需要撥打ReceiveCallback發出下一個BeginReceive呼叫。

由於UDP是無連接的異步IO似乎毫無意義。可能應該使用同步接收循環:

while (true) { 
client.Receive(...); 
ProcessReceivedData(); 
} 

刪除所有異步代碼。

如果你堅持異步IO至少使用ReceiveAsync

+0

如果您認爲它已過時,我應該如何使用'新'的東西。 – TobusBoulton

+0

轉到這些新功能的文檔,並將它們輸入Google。實際上,由於這些功能與舊功能一樣,所以不應該有太大的麻煩。 – usr

-1

msdn代碼有一個你消除的睡眠。你不需要睡覺,但你需要一個塊。嘗試這些更改

 public static void ReceiveMessages() 
     { 
      // Receive a message and write it to the console. 



      UdpState s = new UdpState(); 

      Console.WriteLine("listening for messages"); 
      s.u.BeginReceive(new AsyncCallback(ReceiveCallback), s); 
      //block 
      while (true) ; 
     } 

     public static void RecieveMoreMessages(UdpState s) 
     { 
      s.u.BeginReceive(new AsyncCallback(ReceiveCallback), s); 
     } 

     public static void ReceiveCallback(IAsyncResult ar) 
     { 
      UdpClient u = (UdpClient)((UdpState)(ar.AsyncState)).u; 
      IPEndPoint e = (IPEndPoint)((UdpState)(ar.AsyncState)).e; 

      Byte[] receiveBytes = u.EndReceive(ar, ref e); 
      string receiveString = Encoding.ASCII.GetString(receiveBytes); 

      Console.WriteLine("Received: {0}", receiveString); 
      RecieveMoreMessages(ar.AsyncState); 
     }​ 
+0

'while(true);'這實際上不是暫停線程的方式,因爲它將內核驅動爲100%。我也看不到這個成就。 – usr

+0

在塊上閱讀。塊阻止程序退出。它構建在一個表單項目中,但您需要將一個塊添加到控制檯應用程序。您可以添加睡眠或任何其他停止處理的方法 – jdweng