2

I have a Python protocol running under CentOS 6.4/64-bit. Where i am having TCP server port 7007. In some cases like update new version or maintenance or on the fly restart to refresh buffer i need to restart the application as:

server.py:

class AServer(threading.Thread):
  def __init__(self, port):
    threading.Thread.__init__(self)
    self.port = port

  def run(self):
    host = ''
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind((host, self.port))
    print bgcolors.BOOT
    s.listen(1)
    conn, addr = s.accept()
    print bgcolors.OK + 'contact', addr, 'on', self.now()

    while 1:
      try:
        data = conn.recv(1024)
      except socket.error:
        print bgcolors.OK + 'lost', addr, 'waiting..'
        s.listen(1)
        conn, addr = s.accept()
        print bgcolors.OK + 'contact', addr, 'on', self.now()
        continue
      if not data:
        ..... 
      ...

t = AServer(7007)
t.start()

Restart urgent on the fly (expecting to run within 1 second) but fails:

$ ps aux | awk '/server.py/ {print $2}' | head -1 | xargs kill -9;
$ nohup python /var/tmp/py-protocol/server.py &
[root@IPSecVPN protocol]# python server.py
Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/lib64/python2.6/threading.py", line 532, in __bootstrap_inner
    self.run()
  File "server.py", line 236, in run
    s.bind((host, self.port))
  File "<string>", line 1, in bind
error: [Errno 98] Address already in use

3 Answers3

6

Your socket is in the TIME_WAIT state which is why the address is still in use even though your program has quit. You can set SO_REUSEADDR on the socket to reuse it before the sockets exits the TIME_WAIT state. The Python documentation suggests the following:

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST, PORT))
clj
  • 481
  • 2
  • 8
0

Well, TCP has a TIMEWAIT timer that keeps a connection for some time (approx 2 minutes on most OS). So, if you already have a port bound and connected then closing it might put it in TIMEWAIT state. To be more precise, only one side of the TCP connection is put in TIMEWAIT state.

This is a good discussion on TIMEWAIT: What is the cost of many TIME_WAIT on the server side?

Agree with @clj solution, setting SO_REUSEADDR is a good idea (+1).

Community
  • 1
  • 1
Manoj Pandey
  • 4,528
  • 1
  • 17
  • 18
0

Open your terminal:

ps aux || grep

list all running services and find the id you want to kill.

sudo kill -9 <id you want to kill>
Ayse
  • 576
  • 4
  • 13