2

CentOS 6.4/64 ビットで Python プロトコルを実行しています。TCPサーバーポート7007を使用している場合。新しいバージョンの更新やメンテナンス、またはオンザフライで再起動してバッファを更新する場合は、次のようにアプリケーションを再起動する必要があります。

サーバー.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()

その場で緊急に再起動します (1 秒以内に実行されることを期待しています) が失敗します:

$ 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
4

3 に答える 3

6

ソケットは TIME_WAIT 状態にあるため、プログラムが終了してもアドレスがまだ使用されています。ソケットに SO_REUSEADDR を設定して、ソケットが TIME_WAIT 状態を終了する前にソケットを再利用できます。Python のドキュメントでは、次のことが提案されています。

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST, PORT))
于 2013-09-07T19:18:01.527 に答える
0

TCP には、しばらくの間 (ほとんどの OS で約 2 分間) 接続を維持する TIMEWAIT タイマーがあります。そのため、すでにポートをバインドして接続している場合、それを閉じると TIMEWAIT 状態になる可能性があります。より正確には、TCP 接続の片側だけが TIMEWAIT 状態になります。

これは TIMEWAIT に関する良い議論です:サーバー側で多くの TIME_WAIT のコストはいくらですか?

@clj ソリューションに同意します。SO_REUSEADDR を設定することをお勧めします (+1)。

于 2013-09-07T19:10:20.707 に答える
0

端末を開きます。

ps aux || grep

実行中のすべてのサービスを一覧表示し、強制終了する ID を見つけます。

sudo kill -9 <id you want to kill>
于 2022-02-10T07:52:56.540 に答える