Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

Vorlath

Windows not closing sockets properly. HELP!

This topic is 5949 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

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

Share this post


Link to post
Share on other sites
Advertisement
Guest Anonymous Poster
Have you set the appropriate linger options with (i think) setsockopt ?

Share this post


Link to post
Share on other sites
Are you looking at the netstats 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.

Share this post


Link to post
Share on other sites
Wow, I finally found it!!!


  
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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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().

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
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.

Share this post


Link to post
Share on other sites
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:

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]

Share this post


Link to post
Share on other sites

  • 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!