首页 文章

UDP有时无法接收任何内容

提问于
浏览
3

我有一个C#应用程序从远程主机接收UDP数据 . 我发现有时候我的插座什么都没收到,我似乎无法找到任何关于原因的线索! 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,0,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, 0, byData.Length, SocketFlags.None, new AsyncCallback(OnRecieve), 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,它应该在所有网络接口上接收 .

2 回答

  • 1

    我只是遇到了同样的问题并通过将timeTolive设置为大数据来解决它 .

    _client = new UdpClient();
    _client.Client.Bind(new IPEndPoint(IPAddress.Any, targetURI.Port));
    _client.JoinMulticastGroup(IPAddress.Parse(targetURI.Host) , 250);
    
    • timeToLive = 250,它有效 .

    • timeToLive = 50,工作与否工作交替发生 .

    • timeToLive =无或0,不起作用 .

  • 0

    这种问题的常见原因是没有足够快地处理数据包 . 它们填满套接字接收缓冲区,内核开始丢弃它们 .

    增加套接字receive buffer size以适应流量突发 . 从快速套接字读取路径中删除所有非必要的内容 . 考虑简单的迭代方法,而不是针对线程池:

    rxData = new byte[nBytesRec];
    
    while ( !time_to_stop ) {
        int len = socket.Receive( rxData );
        OnRxBytesEvent( rxData, len );
    }
    

    您的代码评论提到了多播 . 请注意,您需要为此添加显式group membership,以及您在接口上加入多播组(显式或通过路由表决定),因此如果要在两个接口上侦听多播数据,则需要两个套接字 .

相关问题