加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – UDP有时无法接收任何内容

发布时间:2020-12-15 21:38:16 所属栏目:百科 来源:网络整理
导读:我有一个C#应用程序从远程主机接收UDP数据.我发现有时我的插座什么都没收到,我似乎无法找到任何关于原因的线索! Wireshark告诉我我的数据正在从远程设备正确发送.我似乎无法理解为什么有时候我会收到罚款,有时我不能. 我没有任何例外,但OnRecieve永远不会被
我有一个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,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,以及在接口上加入多播组(显式或通过路由表决定),因此如果要在两个接口上侦听多播数据,则需要两个套接字.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读