I have recently started learning Python and I have come across a problem I can't seem to resolve. Since the application I am making is already rather large, I just created a small example script to show the problem I am having:
#!/usr/bin/python
import socket, threading, processing, os
def main():
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind( ('0.0.0.0', 5000) )
server.listen(5)
while 1:
(sock, address) = server.accept()
thread = Worker(sock)
thread.setDaemon(1)
thread.start()
class Worker(threading.Thread):
stage = 0
specialCommands = [
'quit',
'help',
'rset',
]
mailFrom = ""
mailRCPT = []
mailData = ""
def __init__(self, sock):
threading.Thread.__init__(self)
self.sock = sock
def run(self):
loop = 1
self.sock.send("Test\n")
while loop:
str_line = self.sock.recv(1024)
if len(str_line) == 0:
return
self.sock.send("Test\n")
if str_line.strip().lower() == "bye":
loop = 0
self.sock.shutdown(socket.SHUT_RDWR)
self.sock.close()
main()
Its a simple script that opens a socket on port 5000. Now, if you telnet to that port, you will find the following in a netstat:
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 localhost:5000 localhost:50822 ESTABLISHED
tcp 0 0 localhost:50822 localhost:5000 ESTABLISHED
Now, if you send the command "bye" through your telnet session, the Python script should shutdown the socket and close it. The telnet session does end, but it seems the server hasn't actually closed the socket, but left it to wait for the networking system to cleanup. The following is found in a netstat:
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 localhost:5000 localhost:50822 TIME_WAIT
Even if you stop the script, the socket still remains for sometime.
I found that if this happened, if you were to stop and then restart the server, the server would not start because the socket was still considered in use, which led me to add the server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
to prevent this from occurring.
Why is the socket still remaining open even after I have specifically told it to close? How can I stop this from happening?