UDP Clients

Recommended Posts

MeshMan    134
Hi guys, I'm writing a UDP network library (for learning purposes) and I would like to know what the best way of storing unique connected clients is. At the moment, I'm just using the SOCKADDR from when the client first starts sending packets. Does that suffice? Thanks, MeshMan

Share on other sites
markr    1692

Even more specifically, you can also ignore the sa_family member, because it will always be the same.

You should of course always check on an incoming packet, that it's either the start of a new session, or it's coming from an IP address (well, sockaddr_in anyway) that you recognise as part of an existing session.

There are also heaps of other checks you need to do to ensure that packets are not being spoofed and/or are arriving in the appropriate order.

Lots of weird things can happen, including packets arriving in the wrong state because of network congestion.

Mark

Share on other sites
MeshMan    134
My network library is almost up to speed with ENet (apart from the voice stuff which I'm gonna add soon with the help of FMod :)) but what I'm findins is that I keep repeatedly getting a WSAECONNRESET error code from the recvfrom() on my listening server socket and according to MSDN, I don't know what it means by ICMP Port Unreachable. How should I react to this error?
It only happens when a client quits the server and the server doesnt know he has disconnected, and then he connects from the same machine..

Share on other sites
doho    378
MSDN

Here is some source that I used to fix the problem.
void Socket::DisableConnResetError(){	DWORD NewBehaviour;	OSVERSIONINFOEX Info;	// get information about os	WinUtilities::GetOSInfo(&Info);	// platform is win9x or winnt?	if(Info.dwMajorVersion <= 4)	{		return;	}	// platform is win2k with service pack <= 1 installed?	if(Info.dwMajorVersion == 5 && Info.dwMinorVersion == 0 && Info.wServicePackMajor <= 1)	{		return;	}	// platform is either win2k with service pack >= 2 or winxp, so discard WSAECONNRESET errors	NewBehaviour = 0;		if(ioctlsocket(m_Socket, _WSAIOW(IOC_VENDOR, 12), &NewBehaviour) == SOCKET_ERROR)	{		throw Exception(true, "unable to set SIO_UDP_CONNRESET socket option");	}}

Share on other sites
MeshMan    134
Great. Thanks very much.

Share on other sites
markr    1692
I was not aware that Windows actually reported UDP errors in this way, I thought it just dropped them.

Anyway, it's not clear to me how to determine the address of the host which generated the ECONNREFUSED on a UDP socket. Perhaps it fills in the from and fromlen pointers when you call recvfrom() even in this error condition. Presumably it must, otherwise it would be useless on a socket used to service multiple clients. Some research is obviously required to find this out.

If you are not interested, presumably it's safe to ignore the ECONNREFUSED and just call recvfrom again until you get a packet of data.

Mark

Share on other sites
MeshMan    134
I've been in the endless loop error. Gonna need to do some testing to see what best fits.

Share on other sites
MeshMan    134
Quote:
 Original post by markrYou should of course always check on an incoming packet, that it's either the start of a new session, or it's coming from an IP address (well, sockaddr_in anyway) that you recognise as part of an existing session.

Ok. I've reacted to the WSAECONNRESET error by getting the SOCKADDR_IN from the recvfrom() and comparing it to already connected players then booting that client off. All works.

Share on other sites
markr    1692
If by "booting the client off", you mean, just deleteing their entry from the connected clients table (after doing any local cleanup), yes fine.

I can't see any use for sending any more packets to a client after it's got a CONNREFUSED error.

Mark

Share on other sites
MeshMan    134
Yes. Not sending anymore packets to that client, just deleting their entry from my connected list.

What I still don't understand is that if I'm not sending any packets to that socket (or am I?), how come I repeatedly keep getting the WSAECONNRESET error on the socket.

Am I right in thinking that if I try and send a packet to an invalid address, it SOMEHOW?? comes back as a WSAECONNRESET error on my listening socket?

Meshy.

Share on other sites
markr    1692
I believe these errors happen if a remote host or an intermediate router sends back an ICMP unreachable message for that UDP ip adress / port number.

Because it's all a bit asynchronous, it might not come back immediately, you could get one later.

The remote host should send a maximum of one unreachable per UDP datagram received, I would have thought. Moreover, it should apply rate-limiting in case it gets bombarded with invalid UDP packets (Although I think Windows does not implement this).

So unless you're continuing to bombard the host with udp even after it's stopped listening, you shouldn't keep getting these messages back.

Of course any messages that were in transit or queued, may cause responses for that host. So you might get a few. But they should stop after you stop sending to that host.

Are you sure you're processing them on behalf of the right host?

Have you tried it on a lan with several real hosts and with a packet logger watching to see what's happening?

Mark

Share on other sites
MeshMan    134
Thanks for getting back Mark. I'm in the middle or more testing.
I've never used a packet logger before, any good free ones out there you could name for me?

Share on other sites
markr    1692
Ethereal is pretty much what you want.

Mark

Create an account

Register a new account