【问题标题】:How to close socket connection on Ctrl-C in a python programme如何在 python 程序中关闭 Ctrl-C 上的套接字连接
【发布时间】:2015-02-06 05:45:20
【问题描述】:
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()

我在我用 Python 编写的无限运行 TCP 服务器上捕获了KeyboardInterrupt信号。但是,即使我知道它正在关闭连接,因为它打印 Closing Connection,当我尝试重新运行服务器时,我得到:

OSError: [Errno 48] Address already in use

我不知道发生了什么,因为我确定我在打电话给conn.close()

并且运行killall python3并没有修复它,除非我等待很长时间或更改端口,否则我会不断收到错误消息。我也尝试 grep 所有python3 进程,但我什么也没得到。

我正在运行 OS X Yosemite。

【问题讨论】:

  • 您确定错误代码是 48 而不是 98?

标签: python sockets tcp server


【解决方案1】:

您需要为此注册一个钩子,例如:

#!/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)

【讨论】:

【解决方案2】:

根据docs 错误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))

【讨论】:

    猜你喜欢
    • 2015-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    • 2018-11-22
    相关资源
    最近更新 更多