Icmp Ping Multiple Threads

  • Thread starter Thread starter Arsen V.
  • Start date Start date
A

Arsen V.

How to get Icmp messages to work with multiple threads.

Currently I tried during ReceiveFrom and use Peek to get the fromEndPoint.
If this is equals to the EndPoint that I used in SendTo, I do an actual
ReceiveFrom (not Peek).

Otherwise, I continue to loop around and do
ReceiveFrom(...,SocketFlags.Peek,ref fromEndPoint).

However, this does not scale well. With 20 threads it does not work at all.

Any suggestions?
 
Hi Arsen,

Thanks for your posting. As for the Icmp Ping with Multi Threads problem
you mentioned, would you provide some further description on your code
logic or some code snippet ? Also, how do you use multi-threading? As far
as I known, the .net framework's threadpool has a 20 limitation per CPU.
Anyway, please feel free to post some further info or any other concerns so
that we can perform some further test. Thanks.

Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
Hi Steven,

I have a class called "Icmp". It has a method Ping(string host, int
timeout);

This method basically works like this:

1) Get the remoteEndPoint from the host

2) Create a socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw,
ProtocolType.Icmp)

3) Construct the "EchoMessage" byte array using Type=8, Code=0, Id=Some
Unique Id, Data=32 spaces

4) Setup a timer for timeout

5) Do socket.SendTo(buffer, remoteEndPoint)

6) Do socket.ReceiveFrom(buffer, responseEndPoint)

7) Time how long it took to receive the response

8) If timer even fires, close the socket and catch Exceptions

This works without problems on single thread. But if I create an instance of
the Icmp class on multiple threads (even 2) they responses that each thread
receives from ReceiveFrom may belong to the other threads Echo.

I tried changing the login in step 6) to the following:

while(ture)
{
bytesReceived = socket.ReceiveFrom(buffer, SocketFlags.Peek, ref
responseEP);
if (responseEP.ToString() == remoteEP.ToString())
break;
}
bytesReceived = socket.ReceiveFrom(buffer, SocketFlags.None, ref
responseEP);

Hoping that this way each thread would "peek" into the response and only
read it when it belongs to it (based on the match between the responseEP and
the remoteEP to which it sent the packet). However, this does not work.

What's your suggestion?

Thanks,
Arsen
}
 
Hi Arsen,

Thanks for your response. Well, from your description, you're creating
multi threads to send ping ICMP message to different machines and also
recieve until get the certain EndPoint's reply which equals to the one you
sendto, yes?

I'm not very sure what's actual problem you may encounter, but it is likely
that the recieveFrom while loop in your worker threads may cause some
unexpected results since the ICMP ignore the port info so that all those
sockets in your worker threads will possibly get the reply of the other
thread's target machine as you mentioned. And this may cause some
unnecessary loop time.

My suggestion is that we can just create one global socket object for the
whole application(All the ping threads share this global socket). Also, in
all the new created sub ping threads, we only Send the ping message but
don't recieve in it , that means those ping thread will immediately return
after
socket.SendTo...

Then, we need another separate background thread who only do the receiving
work. use a while loop to
constantly call recieveFrom at the global socket object. And each time you
get a reply, you can loop through your own lookup list to compare the
returned EndPoint address with those in the lookup table, (a hashtable is
ok) and find the equal one.

How do you think of this?

If there are any other concerns, please feel free to post here. Thanks.

Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
Back
Top