Python 如果引发 KeyBoardInterrupted,socketserver 不会自动解除绑定
Python socketserver does not unbind automatically if KeyBoardInterrupted is raised
我是 Python 套接字服务器编程的新手,我正在按照此 example 使用套接字服务器框架设置服务器。根据评论,按 Ctrl-C 将停止服务器,但是当我再次尝试 运行 时,我得到
OSError: [Errno 98] Address already in use
这让我不得不使用终端手动终止进程。
根据我的理解,KeyboardInterrupt 被认为是 Python 中的一种异常,当 with
块中发生异常时, Python 也会调用 __exit__()
函数来清理。我试图在 TCP 处理程序 class 中创建一个 __exit__()
函数,但这似乎无法解决问题。
有谁知道引发异常时解除套接字绑定的方法吗?
server.py
import socketserver
from threading import Thread
class MyTCPHandler(socketserver.BaseRequestHandler):
"""
The request handler class for our server.
It is instantiated once per connection to the server, and must
override the handle() method to implement communication to the
client.
"""
def handle(self):
# self.request is the TCP socket connected to the client
self.data = self.request.recv(1024).strip()
print("{} wrote:".format(self.client_address[0]))
print(self.data)
# just send back the same data, but upper-cased
self.request.sendall(self.data.upper())
# Self-written function to try to make Python close the server properly
def __exit__(self):
shutdown_thread = Thread(target=server.shutdown)
shutdown_thread.start()
if __name__ == "__main__":
HOST, PORT = "localhost", 9999
# Create the server, binding to localhost on port 9999
with socketserver.TCPServer((HOST, PORT), MyTCPHandler) as server:
# Activate the server; this will keep running until you
# interrupt the program with Ctrl-C
server.serve_forever()
这不是Python的东西,这是TCP的神器。即使在应用程序终止后,看似关闭的套接字实际上仍处于部分打开状态。要解决这个问题,请使用
socketterver.TCPServer.allow_reuse_address = True
在创建服务器之前。这会启用覆盖此行为的 SO_REUSEADDR 套接字选项。
正如@Tim Roberts 所解释的那样,它是 TCP 的产物。除了他的方法,您还可以使用
手动传递 SO_REUSEADDR
标志
socket.setsockopt(socket.SO_REUSEADDR)
当您传递多个 socketopt
时,或者当您想要更熟悉 C 中的低级网络时,这可能很有用。
我是 Python 套接字服务器编程的新手,我正在按照此 example 使用套接字服务器框架设置服务器。根据评论,按 Ctrl-C 将停止服务器,但是当我再次尝试 运行 时,我得到
OSError: [Errno 98] Address already in use
这让我不得不使用终端手动终止进程。
根据我的理解,KeyboardInterrupt 被认为是 Python 中的一种异常,当 with
块中发生异常时, Python 也会调用 __exit__()
函数来清理。我试图在 TCP 处理程序 class 中创建一个 __exit__()
函数,但这似乎无法解决问题。
有谁知道引发异常时解除套接字绑定的方法吗?
server.py
import socketserver
from threading import Thread
class MyTCPHandler(socketserver.BaseRequestHandler):
"""
The request handler class for our server.
It is instantiated once per connection to the server, and must
override the handle() method to implement communication to the
client.
"""
def handle(self):
# self.request is the TCP socket connected to the client
self.data = self.request.recv(1024).strip()
print("{} wrote:".format(self.client_address[0]))
print(self.data)
# just send back the same data, but upper-cased
self.request.sendall(self.data.upper())
# Self-written function to try to make Python close the server properly
def __exit__(self):
shutdown_thread = Thread(target=server.shutdown)
shutdown_thread.start()
if __name__ == "__main__":
HOST, PORT = "localhost", 9999
# Create the server, binding to localhost on port 9999
with socketserver.TCPServer((HOST, PORT), MyTCPHandler) as server:
# Activate the server; this will keep running until you
# interrupt the program with Ctrl-C
server.serve_forever()
这不是Python的东西,这是TCP的神器。即使在应用程序终止后,看似关闭的套接字实际上仍处于部分打开状态。要解决这个问题,请使用
socketterver.TCPServer.allow_reuse_address = True
在创建服务器之前。这会启用覆盖此行为的 SO_REUSEADDR 套接字选项。
正如@Tim Roberts 所解释的那样,它是 TCP 的产物。除了他的方法,您还可以使用
手动传递SO_REUSEADDR
标志
socket.setsockopt(socket.SO_REUSEADDR)
当您传递多个 socketopt
时,或者当您想要更熟悉 C 中的低级网络时,这可能很有用。