justinman 0 Newbie Poster

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?