Well, for what it's worth, here's the code boiled down to a small console
example. I grabbed 9 IPs from my set and added a bogus IP for the 10th.
I'm not sure what was going on yesterday, but this works great (as
expected). I didn't realize that a WSAECONNRESET error was expected on a
udp socket if the other end is up, but not open on the specified port.
Here's the code - maybe it will be useful to someone else. I suppose you
could use it as a Half-Life server pinger. :-)
using System;
using System.Threadin g;
using System.Net;
using System.Net.Sock ets;
namespace TestUdpSendRecv
{
/// <summary>
/// Summary description for Class1.
/// </summary>
class Class1
{
private static Socket _socket = null;
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
byte[] buffer = {0xFF, 0xFF, 0xFF, 0xFF,
(byte)'p', (byte)'i', (byte)'n', (byte)'g', 0x00};
IPEndPoint[] eps = {
new IPEndPoint(IPAd dress.Parse("19 4.70.27.10"),27 016),
new IPEndPoint(IPAd dress.Parse("21 3.139.175.131") ,27025),
new IPEndPoint(IPAd dress.Parse("64 .156.2.132"),27 019),
new IPEndPoint(IPAd dress.Parse("81 .2.166.133"),27 015),
new IPEndPoint(IPAd dress.Parse("66 .208.100.134"), 27015),
new IPEndPoint(IPAd dress.Parse("62 .73.33.10"),270 15),
new IPEndPoint(IPAd dress.Parse("62 .73.33.10"),270 15),
new IPEndPoint(IPAd dress.Parse("20 8.187.58.4"),27 015),
new IPEndPoint(IPAd dress.Parse("80 .55.110.10"),27 015), // Throws
exception
new IPEndPoint(IPAd dress.Parse("10 .0.0.199"),2701 5) // Invalid IP
};
_socket = new Socket(AddressF amily.InterNetw ork, SocketType.Dgra m,
ProtocolType.Ud p);
// Timeout after 3 seconds
_socket.SetSock etOption(Socket OptionLevel.Soc ket,
SocketOptionNam e.ReceiveTimeou t, 3000);
// Create the receiving thread
Thread recvThread = new Thread(new ThreadStart(rec v) );
recvThread.Name = "Receive Thread";
recvThread.Star t();
int nBytesSent = 0;
for (int i=0; i<eps.Length; i++ )
{
Console.WriteLi ne("Sending to {0}", eps[i]);
nBytesSent = _socket.SendTo( buffer, eps[i]);
//Thread.Sleep(10 ); // Testing - try throttling
}
recvThread.Join ();
_socket.Shutdow n(SocketShutdow n.Both);
_socket.Close() ;
Console.WriteLi ne("Press Enter to exit...");
Console.ReadLin e();
}
private static void recv()
{
// Sleep for a bit - get "invalid option exception" if ReceiveFrom is
called before a send
Thread.Sleep(50 );
byte[] buff = new byte[8192];
int nBytes = 1; // Init to '1' just to get into while loop
IPEndPoint iep = new IPEndPoint(IPAd dress.Any, 0 );
EndPoint ep = (EndPoint)iep;
try
{
while (nBytes > 0)
{
try
{
nBytes = _socket.Receive From(buff, ref ep);
Console.WriteLi ne("{0} bytes from {1}", nBytes, ep);
}
catch (SocketExceptio n ex)
{
if (ex.ErrorCode != 10054 )
{
// Break out of not an 'expected' exception (WSAECONNRESET)
Console.WriteLi ne(ex.Message);
break;
}
Console.WriteLi ne("Caught exception \"{0}\"", ex.Message);
}
}
}
catch (Exception ex)
{
Console.WriteLi ne(ex.Message);
}
}
}
}
"William Stacey" <st***********@ mvps.org> wrote in message
news:#L******** ******@tk2msftn gp13.phx.gbl...
I guess I was just expecting different behavior. I figured that if I
send a UDP packet to an IP that doesn't have anything at the other end that my
"recvFrom() " call would just block forever waiting for something to come
back.
It should unless you set the receive timeout (which I would do). I am
guessing that a host by that IP does, infact, exist and it closed the
connect. Do you get the same behavior using an IP you know for sure does
not exist? If you don't set a timeout, it will wait forever unless it
gets closed (like yours) or get a reply.
Hmm. Maybe I can't do what I'm trying to do. I have a list of IP's
that I need to send an identical packet to and time the round-trip time.
Sounds like ping? You have a udp server program listening on the other
side?
> I could just have one thread just cycling through the IPs sending the
datagram, and having another thread to just read the responses as they
come in.
AFAICT, that should work ok if your sharing the same UdpClient or socket.
As long as one thread does nothing but post sends and the other posts
reads. Again, not sure if socket exceptions will be thrown on the right thread or
in some random fashion. Not sure if this helps, buy I got this reply from
a ms poster awhile back:
"However for some of the user scenarios the UdpClient class can be used
without explicit synchronization .
Such as one thread could be doing read and other thread could be doing
send, fine.
Concurrent Reads are not supported on UdpClient though they are supported
on the socket level.
Concurrent Sends are supported as far as the remote address does not
change."
You could also show the code your using and I could test a few things.
hth
--
William Stacey, MVP