Windows not closing sockets properly. HELP!
Sorry if this has been asked before, but here goes.
I''m writing a multiplayer board game where the server is on Linux and the client runs on Windows. Let''s suppose I run a client (on Linux) from a different box than the server, when I call close() the socket goes away immediately when I look at the netstat output on the server. But from a windows client, when I call closesocket(), the socket lingers around for up to two minutes (the Linux timeout for inproperly closed sockets). I tried shutdown(), but that didn''t do anything.
Anyone come across this problem before? I have a really hard time explaining myself, so...
Linux box1 close() -> Linux server = no problem
Window box closesocket() -> Linux server = socket linger around
help
You need to call shutdown() on the socket before closing it.
Mark Fassett
Laughing Dragon Entertainment
http://www.laughing-dragon.com
Mark Fassett
Laughing Dragon Entertainment
http://www.laughing-dragon.com
June 28, 2002 01:45 AM
Have you set the appropriate linger options with (i think) setsockopt ?
Are you looking at the
codeka.com - Just click it.
netstat
s on the Windows client? It''s possible that you''re just not detecting that the client has disconnected in the server. When you call recv
it''ll return 0, and you''ve got to call close
on the server side as well. You don''t just close it on one end and not the other. codeka.com - Just click it.
Wow, I finally found it!!!
if you don''t wait after the shutdown, it won''t close correctly. How screwed up is that??? You don''t have to do any of this on Linux. Waddup?
shutdown(sock,1); char buffer[1024]; while (0!=recv(sock,buffer,1024,0)); closesocket(sock);
if you don''t wait after the shutdown, it won''t close correctly. How screwed up is that??? You don''t have to do any of this on Linux. Waddup?
quote:
Original post by Vorlath
if you don''t wait after the shutdown, it won''t close correctly. How screwed up is that??? You don''t have to do any of this on Linux. Waddup?
Really? That''s a bad thing you know... If there''s still data waiting there when you try to close the socket, what''s supposed to happen to it? It just goes into oblivion? If there''s no data waiting, then calling
closesocket
will close the socket straight away. codeka.com - Just click it.
There''s no reason to poll recv() if you already know you need to disconnect. Just shutdown and closesocket. If you don''t like the socket lingering, turn off linger as a previous poster said. You can also use the reuseaddr flag if you wanted to restart on that same port for whatever reason before the system releases the socket.
In most client/server applications when one side or the other decides to shutdown it''s connection, there is little reason to process additional data. For instance, you are purposefully calling closesocket(). You KNOW for a fact that you want to close. You obviously don''t care about any remaining data, so why try to read it? Turn off linger and be rid of the problem. Be happy that the connection is being closed explicitly, by choice and not a downed router, crashed client (servers don''t crash! hahaha), or cut cable like commercial games sometimes experience.
In most client/server applications when one side or the other decides to shutdown it''s connection, there is little reason to process additional data. For instance, you are purposefully calling closesocket(). You KNOW for a fact that you want to close. You obviously don''t care about any remaining data, so why try to read it? Turn off linger and be rid of the problem. Be happy that the connection is being closed explicitly, by choice and not a downed router, crashed client (servers don''t crash! hahaha), or cut cable like commercial games sometimes experience.
You ABSOLUTELY HAVE TO POLL recv() when closing a socket on Windows. Everybody using sockets on Windows should do this. I''ll try to explain myself again.
If you do not poll recv(), the socket WILL NOT CLOSE PROPERLY!!!This only happens on Windows. It''s true that I don''t care about the remaining data because I''m closing the socket, but that''s beside the point. The point is that if you don''t poll recv(), Windows will not complete the handshaking for properly closing a socket. Unlike what many believe, closing a socket is not merely discontinuing communications with the other machine. Closing a socket is used to send any remaining data and tell the other machine that we are done using the socket. Windows does not do this UNLESS you poll recv().
If you do not poll recv(), the socket WILL NOT CLOSE PROPERLY!!!This only happens on Windows. It''s true that I don''t care about the remaining data because I''m closing the socket, but that''s beside the point. The point is that if you don''t poll recv(), Windows will not complete the handshaking for properly closing a socket. Unlike what many believe, closing a socket is not merely discontinuing communications with the other machine. Closing a socket is used to send any remaining data and tell the other machine that we are done using the socket. Windows does not do this UNLESS you poll recv().
June 30, 2002 10:06 PM
If you turn lingering off, it will NOT try to send or receive any more data, it will perform a graceful disconenction if no data exists to send or receive, or it will perform a "Hard" disconnection if data is buffered.
Wow, caps and all...
Let me try to explain myself a little better this time. The "problem" you have is called the TIME_WAIT state. It's a normal part of TCP. It does not indicate an error condition. The socket will indeed be closed by the system after the TIME_WAIT state expires (2 minutes on linux typically, 5 minutes on Win2k). This does NOT warrant polling recv(). It is a TCP stack-level detail. It will be dealt with, you don't have to panic. If you need to reuse the port that it is on, then simply use the REUSEADDR socket option. Otherwise, you will be issued an arbitrary port when you restart your client. Again, this is normal and does not warrant any action on your part. If you don't like the TIME_WAIT state in TCP, turn it off with the LINGER options (SO_DONTLINGER or SO_LINGER) as previously suggested above. And this DOES happen on Linux also, as we see it all the time in industry.
From MSDN:
============================
Here is a summary of closesocket behavior:
If SO_DONTLINGER is enabled (the default setting) it always returns immediately—connection is gracefully closed in the background.
============================
Wow, even Microsoft agrees with me on this one. Maybe that's because I've been doing this for a LONG time. I even get paid to do it, imagine that. You asked a question on the forums in a respectful, inquisitive manner. I always try to give help when I can. When you received valid responses from myself and others, you come back with this:
If you found a hack/kludge solution to causing the TIME_WAIT state to end faster than it's normal timeout, that's great, because a lot people can't figure out simple work-arounds on their own. You did, congratulations. Keep in mind that it is a hack, and not a valid solution (to the non-existant problem). But to insinuate that your newly discovered method is the only correct way is sort of a slap in the face to those of us who gave you experienced, knowledgable answers (that YOU asked for).
Sorry, but I'll be skipping your posts in the future.
[edited by - fingh on July 2, 2002 7:48:39 PM]
Let me try to explain myself a little better this time. The "problem" you have is called the TIME_WAIT state. It's a normal part of TCP. It does not indicate an error condition. The socket will indeed be closed by the system after the TIME_WAIT state expires (2 minutes on linux typically, 5 minutes on Win2k). This does NOT warrant polling recv(). It is a TCP stack-level detail. It will be dealt with, you don't have to panic. If you need to reuse the port that it is on, then simply use the REUSEADDR socket option. Otherwise, you will be issued an arbitrary port when you restart your client. Again, this is normal and does not warrant any action on your part. If you don't like the TIME_WAIT state in TCP, turn it off with the LINGER options (SO_DONTLINGER or SO_LINGER) as previously suggested above. And this DOES happen on Linux also, as we see it all the time in industry.
From MSDN:
============================
Here is a summary of closesocket behavior:
If SO_DONTLINGER is enabled (the default setting) it always returns immediately—connection is gracefully closed in the background.
============================
Wow, even Microsoft agrees with me on this one. Maybe that's because I've been doing this for a LONG time. I even get paid to do it, imagine that. You asked a question on the forums in a respectful, inquisitive manner. I always try to give help when I can. When you received valid responses from myself and others, you come back with this:
quote:
You ABSOLUTELY HAVE TO POLL recv() when closing a socket on Windows. Everybody using sockets on Windows should do this. I'll try to explain myself again.
If you do not poll recv(), the socket WILL NOT CLOSE PROPERLY!!!
If you found a hack/kludge solution to causing the TIME_WAIT state to end faster than it's normal timeout, that's great, because a lot people can't figure out simple work-arounds on their own. You did, congratulations. Keep in mind that it is a hack, and not a valid solution (to the non-existant problem). But to insinuate that your newly discovered method is the only correct way is sort of a slap in the face to those of us who gave you experienced, knowledgable answers (that YOU asked for).
Sorry, but I'll be skipping your posts in the future.
[edited by - fingh on July 2, 2002 7:48:39 PM]
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement