.NET C# UDP SNMP Socket Bug
本文关键字:Socket Bug SNMP UDP NET | 更新日期: 2023-09-27 18:14:37
我在一台带有四个网络适配器的计算机上创建了四个套接字,并将每个套接字绑定到一个网络适配器。
下面是我使用的代码:网络适配器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。Socket 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向设备1(192.168.100.1)发送数据,同时绑定到192.168.100.10网络适配器1
套接字2向设备2(192.168.100.1)发送数据,同时绑定到192.168.100.20网络适配器2
套接字3向设备3(192.168.100.1)发送数据,同时绑定到192.168.100.30网络适配器3
套接字4向设备4(192.168.100.1)发送数据,同时绑定到192.168.100.40网络适配器4
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请求创建一个新的。套接字阻塞为真。TTL默认为128。
这适用于90%的SNMP请求,但是对于一组特定的SNMP请求(10%),我看到SNMP _socket.Available
总是返回0。疯狂的是,我可以在Wireshark中看到SNMP响应返回。我确实看到了Wireshark的响应,当_socket.Available > 0
或_socket.Available == 0
时,原始Wireshark数据没有差异。这10%的SNMP请求有时确实有效,但不是一直有效。我确实两次都在Wireshark中看到相同的数据。
我已经尝试了很多故障排除,但底线是我看到的数据响应在Wireshark,但代码仍然显示_socket.Available == 0
。我在想可能是另一个接口在偷数据?即使套接字绑定到另一个网卡,这是可能的吗?
我还尝试了下面的代码,我忽略了_socket.Available
并使用超时而不是睡觉。我得到了相同的结果。
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库中的代码。如果您对这个问题有任何见解或建议,请告诉我。
及时使用UDP接收数据包以清除接收缓冲区是至关重要的,否则您可能会由于缓冲区满而导致丢失。如果读取速度不够快,可能会淹没接收缓冲区。10%的掉落率听起来很多,但这可能是由于你的代码。
在你的代码中我看到Thread.Sleep(4000)
你应该确保数据包没有在接收缓冲区中等待。睡4秒钟有点长了。我已经很多年没有做过TCP/UDP编码了,但是我记得我有最好的结果,当我为每个接收器使用一个单独的线程,并在读取时阻塞,这样操作系统负责在数据准备好时立即唤醒我的线程。
至少将Thread.Sleep(4000)降低到次秒(尝试250或更少),看看是否有所改善。如果是这样,你就走上了正确的道路。可以增加操作系统级别的接收缓冲区大小,但这通常只用于极端情况,如果您的用户代码编写得很好,则不需要这样做。
同样,我认为没有理由不断地打开/关闭套接字。保持打开。
这里的问题原来是路由问题,因为PC被混淆了,因为在另一端有类似的网络。