27

In network programming in unix, I have always set the SO_REUSEADDR option on the socket being used by server to listen to connections on. This basically says that another socket can be opened on the same port on the machine. This is useful when recovering from a crash and the socket was not properly closed - the app can be restarted and it will simply open another socket on the same port and continue listening.

My question is, what happens to the old socket? Without a doubt, all data/connections will still be received on the old socket. Does it get closed automatically by the OS?

genpfault
  • 51,148
  • 11
  • 85
  • 139
Naren
  • 704
  • 1
  • 7
  • 15
  • 1
    To clarify: After a program crashes, the OS e.g. Linux Kernel, will close the socket automatically. There are protocol-reasons (TCP) why you don't want to reopen a connection immediately. – unixman83 Jan 29 '12 at 08:39
  • 3
    A must read on this topic: http://www.serverframework.com/asynchronousevents/2011/01/time-wait-and-its-design-implications-for-protocols-and-scalable-servers.html –  Apr 03 '12 at 08:57

2 Answers2

31

A socket is considered closed when the program that was using it dies. That much is handled by the OS, and the OS will refuse to accept any further communication from the dead conversation. However, if the socket was closed unexpectedly, the computer on the other end might not know that the conversation is over, and may still be attempting to communicate.

That is why there is, designed into the TCP spec, a waiting period before that same port number can be reused. Because in theory, however unlikely, it may be possible for a packet from the old conversation to arrive with the appropriate IP address, port numbers, and sequence numbers such that the receiving server mistakenly inserts it into the wrong TCP stream by accident.

The SO_REUSEADDR option overrides that behavior, allowing you to reuse the port immediately. Effectively, you're saying: "I understand the risks and would like to use the port anyway."

tylerl
  • 30,197
  • 13
  • 80
  • 113
25

Yes, the OS automatically closes the previous socket when the old process ends. The reason you can't normally listen on the same port right away is because the socket, though closed, remains in the 2MSL state for some amount of time (generally a few minutes). The OS automatically transitions the old socket out of this state when the timeout expires.

Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
  • Ahh.. of course. The socket is just a file handle after all and will get cleaned up by the OS. Thank you very much :) – Naren Apr 22 '09 at 04:19
  • 4
    To be precise, the TCP endpoint remains in the 2MSL state. The socket is gone. – David Schwartz Jan 12 '12 at 02:34
  • 1
    The Waiting-Period was added to the spec for a reason. Using SO_REUSEADDR causes the TCP stack to violate the waiting-period. (Your 2MSL State) – unixman83 Jan 29 '12 at 08:43