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接口,但它为我工作。