C#多播UDP连接,BeginReceiveFrom异步呼叫停止被称为

问题描述:

这是我的第一篇文章,对不起,如果我做我不应该做的事情。我总是在这里寻找答案,但这次我没有看到我的问题。我在C#中有一个项目,我保持连接UDP从数据流中监听多播IP。C#多播UDP连接,BeginReceiveFrom异步呼叫停止被称为

我正在监听的IP是一个多播流媒体,可以从多个跟踪系统发送跟踪数据,因此我们可以假设发送者不是问题。它发送像1024字节的数据包,60 fps。

这是一个从整个项目中提取的小例子,简化了,就我测试的情况而言,其行为方式与大项目中的相同。问题是,如果我在本地连接,这永远不会中断,但如果我连接到远程IP,这停止工作,或多或少,在4分钟内。

public class TrackingStateObject 
{ 
    public Socket workSocket = null; 
    public const int BUFFER_SIZE = 65507; 
    public byte[] buffer = new byte[BUFFER_SIZE]; 
} 

class MainClass 
{ 
    static public string multicastServerIPAddress = "239.255.42.99"; 
    static public string realTrackingServerIPAddress = "161.116.27.144"; 
    static protected EndPoint trackingEndPoint; 

    static public int dataPort = 2345; 
    static protected Socket sockData = null; 

    static int foo = 0; 

    public static void Main (string[] args) 
    { 
     IPEndPoint ipep; 
     TrackingStateObject so; 

     IPAddress trackingIP = IPAddress.Parse(multicastServerIPAddress); 
     trackingEndPoint = new IPEndPoint(trackingIP, dataPort); 
     sockData = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); 

     ipep = new IPEndPoint(IPAddress.Any, dataPort); 

     try { 
      sockData.Bind(ipep); 
     } 
     catch (Exception ex) { 
      System.Console.WriteLine("[UDPClient] Exception "+ex.Message); 
      return; 
     } 

     sockData.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(trackingIP)); 
     try { 
      trackingIP = IPAddress.Parse(realTrackingServerIPAddress); 
      trackingEndPoint = new IPEndPoint(trackingIP, dataPort); 
     } 
     catch(Exception ex) { 
      System.Console.WriteLine("[UDPClient] Exception "+ex.Message); 
      return; 
     } 

     so = new TrackingStateObject(); 
     so.workSocket = sockData; 
     sockData.BeginReceiveFrom(so.buffer, 0, TrackingStateObject.BUFFER_SIZE, 0, ref trackingEndPoint, new AsyncCallback(AsyncReceiveCallback), so); 

     System.Threading.Thread.Sleep (600000); 
    } 

    private static void AsyncReceiveCallback(IAsyncResult ar) 
    { 
     try { 
      TrackingStateObject so = (TrackingStateObject)ar.AsyncState; 
      Socket sock = so.workSocket; 
      int read = sock.EndReceiveFrom(ar, ref trackingEndPoint); 
      if (read > 0) 
      { 
       // Do things with the data 
       System.Console.WriteLine("Recieved shit, " + read + " bytes, " + foo++ + " times."); 
      } 

      sock.BeginReceiveFrom(so.buffer, 0, TrackingStateObject.BUFFER_SIZE, SocketFlags.None, ref trackingEndPoint, new AsyncCallback(AsyncReceiveCallback), so); 
     } 
     catch (Exception e) { 
      System.Console.WriteLine("[UDPClient] Exception AsynCallback "+e.Message); 
     } 
    } 
} 

我调试了一段时间,据我可以看到的是,总是sock.BeginReceiveFrom被调用时,停在某一点上,AsyncReceiveCallback永远不会再次执行。也许我在这里做了一些愚蠢的事情,但无论如何,我都无法看到它。谢谢!

我有完全相同的问题,这似乎只发生在WiFi接口,而不是硬接线接口。我发现的解决方案是在拨打BeginReceiveFrom()之前始终设置SocketOptionName.AddMembership选项。

在接收回调中,在呼叫EndReceiveFrom()之后,然后设置组播地址的SocketOptionName.DropMembership选项。

然后再次致电BeginReceiveFrom()之前,请设置SocketOptionName.AddMembership选项。

不知道为什么这必须做WiFi接口,但它为我工作。