代码之家  ›  专栏  ›  技术社区  ›  Nitrous

.NET C#UDP SNMP套接字错误[已关闭]

  •  0
  • Nitrous  · 技术社区  · 11 年前

    我在一台带有四个网络适配器的计算机上创建四个套接字,并将每个套接字绑定到一个网络适配器。

    网络适配器1位于192.168.100.10。套接字1绑定到网络适配器1
    网络适配器2位于192.168.100.20。套接字2绑定到网络适配器2
    网络适配器3位于192.168.100.30。套接字3绑定到网络适配器3
    网络适配器4位于192.168.100.40。套接字4绑定到网络适配器4

    下面是我使用的代码:

    Socket _socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
    IPEndPoint ipEndPoint = new IPEndPoint(localIP, 0);
    EndPoint ep = (EndPoint)ipEndPoint;
    

    每个网络适配器都有一个本地网络,具有一个IP 192.168.100.1的不同设备。我向该设备发送SNMP(UDP协议)请求数据。

    套接字1在绑定到192.168.100.10网络适配器1时向设备1(192.168.100.1)发送数据
    套接字2在绑定到192.168.100.20网络适配器2时向设备2(192.168.100.1)发送数据
    套接字3在绑定到192.168.100.30网络适配器3时向设备3(192.168.100.1)发送数据
    套接字4在绑定到192.168.100.40网络适配器4时向设备4(192.168.100.1)发送数据

    EndPoint remote = (EndPoint)new IPEndPoint(peer.AddressFamily == AddressFamily.InterNetwork ?    IPAddress.Any : IPAddress.IPv6Any,0);
    
    IPEndPoint ipEndPoint = new IPEndPoint(_localIP, 0);
    EndPoint ep = (EndPoint)ipEndPoint;
    _socket.Bind(ep);
    
    byte[] inbuffer = new byte[64 * 1024]; 
    _socket.SendTo(buffer, bufferLength, SocketFlags.None, (EndPoint)netPeer); //bufer has the  snmp   request
    Thread.Sleep(4000);
    if (_socket.Available > 0)
    {
      recv = _socket.ReceiveFrom(inbuffer, ref remote);
    }
    _socket.Close();
    

    上面的代码是在四个线程中创建的,每个套接字总是在发送和接收数据。发送一个数据请求和响应后,套接字关闭。将为下一个SNMP请求创建一个新的SNMP请求。套接字阻塞是真的。TTL默认为128。

    这适用于90%的SNMP请求,但是对于一组特定的SNMP请求(10%),我看到SNMP _socket.Available 始终返回0。疯狂的是,我可以在Wireshark中看到SNMP响应。我确实在Wireshark中看到了响应,并且当 _socket.Available > 0 _socket.Available == 0 这10%的SNMP请求有时有效,但不是一直有效。我确实两次在Wireshark中看到相同的数据。

    我已经尝试了很多故障排除,但最重要的是我在Wireshark中看到了数据响应,但代码仍然显示 _套接字。可用==0 。我在想可能其他套接字中的一个正在窃取数据?即使套接字绑定到另一个网卡,这也是可能的吗?

    我还尝试了以下代码,其中忽略了 _套接字。可用 使用超时而不是睡觉。我得到了同样的结果。

    IPEndPoint ipEndPoint = new IPEndPoint(_localIP, 0);
    EndPoint ep = (EndPoint)ipEndPoint;
    _socket.Bind(ep);
    _socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, timeout);
    _socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, timeout);
    _socket.SendTo(buffer, bufferLength, SocketFlags.None, (EndPoint)netPeer);
    recv = _socket.ReceiveFrom(inbuffer, ref remote); 
    

    我本来打算一次只运行一个套接字,但这会降低程序的速度。

    我还打算尝试两个套接字,一个用于发送,另一个用于接收,看看它是否修复了这个问题。

    有什么想法吗?我实际上使用了SnmpSharpNet库中的很多代码。如果您对此问题有任何见解或建议,请告诉我。

    2 回复  |  直到 11 年前
        1
  •  0
  •   mrjoltcola    11 年前

    使用UDP及时接收数据包以清除接收缓冲区非常重要,否则可能会因缓冲区已满而导致数据包丢失。如果读取速度不够快,可能会淹没接收缓冲区。10%的下降率听起来很高,但这可能是由于您的代码。

    在您的代码中,我看到Thread.Sleep(4000)

    您应该确保数据包没有在接收缓冲区中等待。睡4秒钟有点多。我已经好几年没有做过很多TCP/UDP编码了,但我记得很清楚,当我为每个接收器使用一个单独的线程,并且在读取时被阻止时,我使用UDP的效果最好,这样操作系统就负责在数据准备就绪时立即唤醒我的线程。

    至少,将Thread.Sleep(4000)降低到每秒(尝试250或更少),看看是否有所改善。如果是这样,你就走上了正确的轨道。可以增加OS级别的接收缓冲区大小,但这通常仅适用于极端情况,如果用户代码编写良好,则不需要这样做。

    此外,我认为没有理由持续打开/关闭插座。保持打开。

        2
  •  0
  •   Nitrous    9 年前

    这里的问题被证明是路由问题,因为PC由于另一端有类似的网络而变得混乱。