2013-12-19 45 views
2

這是我的第一篇文章,對不起,如果我做我不應該做的事情。我總是在這裏尋找答案,但這次我沒有看到我的問題。我在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永遠不會再次執行。也許我在這裏做了一些愚蠢的事情,但無論如何,我都無法看到它。謝謝!

回答

0

我有完全相同的問題,這似乎只發生在WiFi接口,而不是硬接線接口。我發現的解決方案是在撥打BeginReceiveFrom()之前始終設置SocketOptionName.AddMembership選項。

在接收回調中,在呼叫EndReceiveFrom()之後,然後設置組播地址的SocketOptionName.DropMembership選項。

然後再次致電BeginReceiveFrom()之前,請設置SocketOptionName.AddMembership選項。

不知道爲什麼這必須做WiFi接口,但它爲我工作。