我有一个C#应用程序从远程主机接收UDP数据.我发现有时我的插座什么都没收到,我似乎无法找到任何关于原因的线索!
Wireshark告诉我我的数据正在从远程设备正确发送.我似乎无法理解为什么有时候我会收到罚款,有时我不能.
Wireshark告诉我我的数据正在从远程设备正确发送.我似乎无法理解为什么有时候我会收到罚款,有时我不能.
我没有任何例外,但OnRecieve永远不会被调用
这是我的代码,以防它有帮助:
class cUdpRx { private Thread rxThread = null; private Socket UdpSocket; private IPEndPoint localEp; byte[] byData; //rxbytes event public delegate void OnRxBytesEventHandler(byte[] rxBuf); public event OnRxBytesEventHandler OnRxBytesEvent; /// <summary> /// Creates the udp socket /// </summary> /// <param name="Port"></param> /// <returns></returns> public bool CreateSocket(int Port) { try { byData = new byte[1500]; //create our buffer UdpSocket = new Socket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp); UdpSocket.SetSocketoption(SocketoptionLevel.socket,SocketoptionName.ReuseAddress,true); localEp = new IPEndPoint(IPAddress.Any,Port); UdpSocket.Bind(localEp); UdpSocket.BeginReceive(byData,byData.Length,SocketFlags.None,new AsyncCallback(OnRecieve),UdpSocket); return true; //seemed to work ok } catch { dispose(); return false; //something went wrong,abort } } private void OnRecieve(IAsyncResult iar) { byte[] rxData; int nBytesRec = 0; Socket socket = (Socket)iar.AsyncState; try //in case something else has already disposed of the socket { nBytesRec = socket.EndReceive(iar); } catch { Debug.WriteLine("cant access udp rx socket"); } try { if (nBytesRec > 0) { rxData = new byte[nBytesRec]; Array.copy(byData,rxData,nBytesRec); //copy exact data into new array OnRxBytesEvent(rxData); } if(!killThreads) UdpSocket.BeginReceive(byData,UdpSocket); } catch(SocketException se) { Debug.WriteLine(se.ToString()); } }
任何帮助都会非常感激,因为它阻止了我继续我的项目.谢谢
UPDATE
好像使用Ipadress.any是问题所在.如果我改变:
localEp = new IPEndPoint(IPAddress.Any,Port);
至
localEp = new IPEndPoint(IPAddress.Parse("192.168.0.33"),Port);
其中192.168.0.33是我的计算机的IP地址,它每次都会接收数据.
有谁能解释为什么?
使用IPAddress.any并从无线和有线连接接收是非常有用的.
IPAddress.any相当于0.0.0.0,根据MSDN,它应该在所有网络接口上接收.
解决方法
这种问题的常见原因是没有足够快地处理数据包.它们填满套接字接收缓冲区,内核开始丢弃它们.
增加插座receive buffer size以适应流量突发.
从快速套接字读取路径中删除所有非必要的内容.
考虑简单的迭代方法,而不是针对线程池:
rxData = new byte[nBytesRec]; while ( !time_to_stop ) { int len = socket.Receive( rxData ); OnRxBytesEvent( rxData,len ); }
您的代码评论提到了多播.请注意,您需要为此添加显式group membership,以及在接口上加入多播组(显式或通过路由表决定),因此如果要在两个接口上侦听多播数据,则需要两个套接字.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。