Как закрыть соединение сокета на Ctrl-C в программе python

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind((HOST, PORT)) s.listen(1) any_connection = False while True: try: conn, addr = s.accept() data = conn.recv(1024) any_connection = True # keep looking if not data: continue pid = os.fork() if pid == 0: server_process(data, conn) except KeyboardInterrupt: break if any_connection: print("Closing connection") conn.close() 

Я KeyboardInterrupt сигнал KeyboardInterrupt здесь на бесконечно запущенном TCP-сервере, который я написал в Python. Однако, хотя я знаю, что он закрывает соединение, потому что он печатает Closing Connection , когда я пытаюсь перезапустить сервер, я получаю:

OSError: [Errno 48] Address already in use

Я понятия не имею, что происходит, потому что я точно знаю, что conn.close() .

И запуск killall python3 не исправляет его, я продолжаю получать ошибку, если не дождаться долгого времени или изменить порт. Также я попытался grep все процессы python3 но ничего не получаю.

Я запускаю OS X Yosemite.

2 Solutions collect form web for “Как закрыть соединение сокета на Ctrl-C в программе python”

В соответствии с документами ошибка OSError: [Errno 48] Address already in use потому что предыдущее выполнение вашего скрипта покинуло сокет в состоянии TIME_WAIT и не может быть немедленно использовано повторно. Это можно решить, используя флаг socket.SO_REUSEADDR .

Например:

 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind((HOST, PORT)) 

Вам нужно зарегистрировать крючок для этого, что-то вроде:

 #!/usr/bin/env python import signal import sys def signal_handler(signal, frame): # close the socket here sys.exit(0) signal.signal(signal.SIGINT, signal_handler) 
Python - лучший язык программирования в мире.