Sign in to follow this  

Client and server on same machine causes infinite packet loop

This topic is 2126 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've created a client-server scenario, first using broadcast and then moving on to multicasting as an improvement. I began noticing problems in how the networking handled based on whether the client or server opened up first. For example, if I start the server and THEN the client, the client won't be able to read anything from the server, but the other way around worked fine. Turns out that binding both the server and the client on the same port isn't a good idea and doesn't work.

However, my next problem isn't as simple as far as I can tell. In addition to sending a 'disconnect' packet if the client or server closes down, they also send heartbeats in the case that the disconnect packet does not arrive, e.g. the program crashes for any reason.

Now here's the problem scenario:

The server and client are both running.
The server sends a 'ping' every second and the client receives it.
If the client has not received a ping for 10 seconds, the server is removed from the server list.

However, if I close the server, rather than the client ceasing to receive pings, it seems to continue receiving them every single second.

I know it's simply a stack of messages in the buffer because even if I run the server for only around 2 seconds, it will continue to receive pings endlessly, and it's only sending them once a second as verified with some logging.

The server and client use a similar yet basic setup:
-Initiate winsock
-Create a socket
-Bind to port 12345 and 12346 for client and server respectively on INADDR_ANY.
-Send to a multicast address
-select() to determine if there are messages and receive them

Here's a somewhat stripped-down version of the client's receiving code:
[code]
fd_set checksockets;
checksockets.fd_count = 1;
checksockets.fd_array[0]=m_socket;
struct timeval t;
t.tv_sec=0;
t.tv_usec=0;
int waiting = select(NULL, &checksockets, NULL, NULL, &t);

// If there is at least one packet receive it.
if (waiting>0) {
sockaddr senderAddr;
int senderAddrSize = sizeof (senderAddr);
recvfrom(m_socket,buf,10000,0,&senderAddr,&senderAddrSize);
switch(((Packet*)buf)->m_type) {
case PT_SERVERPACKET: {
for (auto it = m_serverList.begin();it != m_serverList.end();++it) {
if (((sockaddr_in*)&(*it).m_address)->sin_addr.s_addr == ((sockaddr_in*)&senderAddr)->sin_addr.s_addr) {
OutputDebugString("Server ping.\n"); // Server ping!
}
}
} break;
}
}[/code]

Share this post


Link to post
Share on other sites
You are not checking the result code from recvfrom(). Thus, whatever was in the buffer before, is still there. You must check recvfrom(), and only read as many bytes as it says you received. If it returns negative, then there's an error. (On Windows, there may be errors on UDP sockets even when the socket is still good -- check its behavior for ICMP port not reached)

Also: multicast doesn't work on the greater Internet, because it's simply not scalable. If you only want to run in local networks with multicast support, feel free to keep using it.

Share this post


Link to post
Share on other sites

This topic is 2126 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this