这是我的第一篇文章,如果我做了我不应该做的事,请提前对不起。我总是在这里寻找答案,但这次我没有看到我的问题。我在C#中有一个项目,我保持连接UDP从数据流中侦听多播IP。
我正在监听的IP是一个多播流媒体,它从许多跟踪系统发送跟踪数据,因此我们可以假设发送方不是问题。它发送类似1024字节的数据包,60 fps。
这是从整个项目中提取的一个小例子,简化并且就我测试而言,其行为与大项目中的行为相同。问题是,如果我在localhost中连接,这永远不会中断,但如果我连接到远程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 :(得分:0)
我遇到了完全相同的问题,这似乎只出现在WiFi接口上,而不是硬连线接口上。我发现的解决方案是在调用SocketOptionName.AddMembership
之前始终设置BeginReceiveFrom()
选项。
在接收回调中,在调用EndReceiveFrom()
之后,为多播地址设置SocketOptionName.DropMembership
选项。
然后再次致电BeginReceiveFrom()
之前,请设置SocketOptionName.AddMembership
选项。
不确定为什么必须为WiFi接口做这件事,但它对我有用。