2015-07-19 172 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