No TIME_WAIT
s on Mac OS X
Normally, when a TCP connection is closed, the socket on the side where close()
is called first is left in the TIME_WAIT
state.
When one of the peers is a Mac OS X (Lion) machine, no TIME_WAIT
is listed by netstat -an
on the Mac if close()
is called first on the Mac side. However, it seems that the socket is actually in TIME_WAIT
state, because trying to call listen()
again (without using the socket option SO_REUSEADDR
) causes listen()
to fail.
Waiting for 2*MSL (Maximum Segment Lifetime which is 15 seconds on Mac OS X Lion as reported by sysctl net.inet.tcp.msl
) clears the TIME_WAIT
state, and listen()
can be called again without error.
Why can't I see the socket in TIME_WAIT
?
Testing
Here are two simple test programs in Python.
Server
#!/usr/bin/env python
import socket
HOST = ''
PORT = 50007
l = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
l.bind((HOST, PORT))
l.listen(1)
print("Listening on %d" % PORT)
(s, _) = l.accept()
print("Connected")
raw_input("Press <enter> to close...")
l.close()
s.close()
print("Closed")
Client
#!/usr/bin/env python
import socket
import sys
HOST = sys.argv[1]
PORT = 50007
print("Opening connection to server")
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
raw_input("Press <enter> to close...")
s.close()
print("Closed")
When running both the server and the client on two different Linux machines, the peer that press <enter>
to call close()
first gets a TIME_WAIT
as expected:
$ ./server-timewait.py
Listening on 50007
Connected
Press <enter> to close...
Closed
$ netstat -an | grep 50007
tcp 0 0 172.16.185.219:50007 172.16.185.42:49818 TIME_WAIT
$
When one of the peers is a Mac (running OS X Lion) I never see a TIME_WAIT
when running netstat -an | grep 50007
after closing first on the Mac.