Click here to Skip to main content
15,880,405 members
Please Sign up or sign in to vote.
5.00/5 (3 votes)
Please help with this problem be patient and read through to the end. I will really appreciate it!!!

I am creating 4 sockets on a computer with 4 network adapters and binding each socket to 1 network adapter.
Network Adapter 1 is at 192.168.100.10. Socket 1 binds to Network Adapter 1
Network Adapter 2 is at 192.168.100.20. Socket 2 binds to Network Adapter 2
Network Adapter 3 is at 192.168.100.30. Socket 3 binds to Network Adapter 3
Network Adapter 4 is at 192.168.100.40. Socket 4 binds to Network Adapter 4
Below is code I use.

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


Each network adapter has a Local Network with one different device at IP 192.168.100.1. I send SNMP (UDP protocol) request data to this device.
Socket 1 sends data to device 1 (192.168.100.1) while binded to 192.168.100.10 Network Adapter 1
Socket 2 sends data to device 2 (192.168.100.1) while binded to 192.168.100.20 Network Adapter 2
Socket 3 sends data to device 3 (192.168.100.1) while binded to 192.168.100.30 Network Adapter 3
Socket 4 sends data to device 4 (192.168.100.1) while binded to 192.168.100.40 Network Adapter 4

C#
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();


The above code is created in 4 threads and each socket is always sending and receiving data. After sending 1 data request and response, the socket gets Closed. A new one is created for the next SNMP request. Socket blocking is true. TTL is 128 by default.

This works for 90% of the SNMP request. However for 1 particular set of SNMP requests(10%), I see that the SNMP _socket.Available always returns 0. The crazy thing is that I can see the data SNMP respsonse come back in Wire-Shark. I do see the response in Wireshark an there is no difference in the raw wireshark data when _socket.Available >0 or _socket.Available = 0. This 10% of SNMP request actually work sometimes and doesn't work sometime. I do see the same data in wire-shark both times.

I tried a lot of troubleshooting but the bottom line is that I see the data response in Wireshark but the code still shows _socket.Available=0. I was thinking that maybe that one of the other sockets is stealing the data? Is that possible even though the socket is binding to another network card?

I also tried the below code where I ignored the _socket.Available and use Timeouts instead of Sleeping. I get the same result.
C#
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);



I was going to have only one socket run at a single time but that will slow down the program.

I was also going to try 2 sockets, one for send and one fore receive to see if it fixes it.

Any ideas? I am using a lot of the code in SNMPSharpNet library actually. Please let me know if you have any insight into this issue or any suggestions.


Thanks!!
Posted
Updated 22-Jul-14 20:35pm
v8
Comments
Mehdi Gholam 20-Jul-14 10:43am    
You are aware that UDP does not guarantee delivery.
nitrous_007 20-Jul-14 12:34pm    
Ok. but I see delivery in wire-shark. So I am expecting the packet to captured in my socket also. What could be happening here?
nitrous_007 20-Jul-14 15:39pm    
I did find something. I have to set Socket Options before the bind to get socket options to be working. I was setting Socket options after bind but this is alternative code I tried. I will try this alternative code again with the fix
johannesnestler 21-Jul-14 10:28am    
Did you solve it? - btw one of the "best" formulated questions I have seen on QA!
nitrous_007 24-Jul-14 21:47pm    
Thanks unfortunately No. The problem remains. I guess nobody does this kind of coding.

Nice article which might answer some of my questions
http://msdn.microsoft.com/en-us/magazine/cc163648.aspx[^]

In my code I am using syrnchronous ReceiveFrom function instead of the asyncronous BeginReceiveFrom. Is there any problem using the syncronous version as I am sending some data and only expection 1 returned buffer.

According to this article, it says that UDP will drop packets upon receipt if even momentarily, BeginReceiveFrom is not active on the socket. This is under the heading 'Reliability Procotols'. It goes on to say that 'there is a short span of time between acceptance of a packet and calling from another BeginReceiveFrom. Even if this call wre the first one in MessageReceivedCallback, there's a short period when the app isn't listening'.
I pasted the code form the link for reference below-
C#
Socket receiveSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); 
EndPoint bindEndPoint = new IPEndPoint(IPAddress.Any, ProtocolPort);
byte[] recBuffer = new byte[PlayerInfo.MaxWireSize];
receiveSocket.Bind(bindEndPoint);
receiveSocket.BeginReceiveFrom(recBuffer, 0, recBuffer.Length, SocketFlags.None, ref bindEndPoint, new AsyncCallback(MessageReceivedCallback), (object)this);
void MessageReceivedCallback(IAsyncResult result) { EndPoint remoteEndPoint = new IPEndPoint(0, 0); 
try {
int bytesRead = receiveSocket.EndReceiveFrom(result, ref remoteEndPoint); player.FromBuffer(recBuffer, 0, Math.Min(recBuffer.Length, bytesRead));
} 
catch (SocketException e) 
{
Console.WriteLine("Error: {0} {1}", e.ErrorCode, e.Message); 
} 
receiveSocket.BeginReceiveFrom(recBuffer, 0, recBuffer.Length, SocketFlags.None, ref bindEndPoint, new AsyncCallback(MessageReceivedCallback), (object)this); }

In my code, I am using the same socket for sending and recieve. I was led to believe that the bind fuction to the IP would automatically buffer all the packets arriving at that network card so that even if the BeginReceive or ReceiveFrom function is not called immediately, the data would be in the buffer. This I believe is correct for TCP/IP connections anyway. Is this different for UDP????
 
Share this answer
 
v3
The solution turned out to be fixing the routes on the Test PC to make sure all the IP's were talking to correct network interfaces.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900