Jump to content
  • Advertisement
Sign in to follow this  
JJJohan

Client and server on same machine causes infinite packet loop

This topic is 2375 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:

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;
}
}

Share this post


Link to post
Share on other sites
Advertisement
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
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!