I am new to socket programming and ran into a puzzling problem:
I have a windows program which I cannot alter (proprietary software) but which tries to connect to a specific ip and port with a tcp socket.
On my linux box I wrote a little python script to serve the socket to the win prog. This works fine until I kill my prog on linux. The initial server socket doesn't close as specified and I cannot restart my program until the socket is garbage collected.
If I try the same with a linux socket (in a seperate python script) I have no problems.
Here is a minimal code example:
import socket
server = socket.socket()
server.bind(('192.168.0.111', 50001))
server.listen(1)
conn, addr = server.accept()
print 'Connection established'
running = True
while running:
try:
data = conn.recv(4096)
except KeyboardInterrupt:
conn.close()
running = False
else:
if data:
print data
else:
conn.close()
running = False
server.close()
If I kill this with Ctrl-C it exits normally. But upon restarting the script I get a socket.error stating the address is already in use. After a minute or so the program works again.
I also tried a shutdown before the close (aka conn.shutdown(2) and server.shutdown...) but that has no effect.
Is there a better 'right' way to close a windows socket? Do I miss something fundamental about sockets in general?
Thanks!
edit: I think I just saw the answer here: what is the correct way to close a socket in python 2.6?
Although I'm using python 2.5 it might still work.
You are experiencing the TIME_WAIT
state of connected sockets. Even though you've closed your socket, it still has lingering consequences for a couple minutes. The reasons for this, as well as a socket flag you can set to disable the behavior (SO_REUSEADDR), are explained in the UNIX guide socket FAQ.
In short,
server = socket.socket()
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(...)
...
Try adding import sys and terminating your app with sys.exit(). The socket stays reserved until the system is satisfied that the application is closed. You can be explicit about that with sys.exit()
[edit]Oh, ok. I am pretty new to sockets myself. So you are saying that this sequence is not safe? I cant imagine any other way to do it. You have to close your app at some point, with some technique, right? How is it correctly done then?
server.shutdown(socket.SHUT_RDWR)
server.close()
sys.exit()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With