gpt4 book ai didi

python - 在单线程 Python 应用程序中关闭 socketserver serve_forever()

转载 作者:太空狗 更新时间:2023-10-29 16:53:11 27 4
gpt4 key购买 nike

我知道socketserver有一个方法shutdown()这会导致服务器关闭,但这仅适用于多线程应用程序,因为关闭需要从与 serve_forever() 所在的线程不同的线程调用正在运行。

我的应用程序一次只处理一个请求,所以我不使用单独的线程来处理请求,而且我无法调用 shutdown()因为它会导致死锁(它不在文档中,但在 socketserver 的源代码中直接说明)。

为了更好地理解,我将在此处粘贴我的代码的简化版本:

import socketserver

class TCPServerV4(socketserver.TCPServer):
address_family = socket.AF_INET
allow_reuse_address = True

class TCPHandler(socketserver.BaseRequestHandler):
def handle(self):
try:
data = self.request.recv(4096)
except KeyboardInterrupt:
server.shutdown()

server = TCPServerV4((host, port), TCPHandler)
server.server_forever()

我知道此代码无效。我只是想向您展示我想完成的事情 - 在用户按下 CtrlC 时关闭服务器并退出应用程序,同时等待传入数据。

最佳答案

您可以在处理程序中本地启动另一个线程,然后从那里调用 shutdown

工作演示:

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

import SimpleHTTPServer
import SocketServer
import time
import thread

class MyHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
def do_POST(self):
if self.path.startswith('/kill_server'):
print "Server is going down, run it again manually!"
def kill_me_please(server):
server.shutdown()
thread.start_new_thread(kill_me_please, (httpd,))
self.send_error(500)

class MyTCPServer(SocketServer.TCPServer):
def server_bind(self):
import socket
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.socket.bind(self.server_address)

server_address = ('', 8000)
httpd = MyTCPServer(server_address, MyHandler)
try:
httpd.serve_forever()
except KeyboardInterrupt:
pass
httpd.server_close()

一些注意事项:

  1. 要终止服务器,请向 http://localhost:8000/kill_server 发送POST 请求。
  2. 我创建调用 server.shutdown() 的函数并从另一个线程运行它以解决我们讨论的问题。
  3. 我使用来自 Binding Socket: “Address already in use” 的建议使套接字立即可供重用(您可以再次运行服务器而不会出现[Errno 98] Address already in use 错误)。使用标准的 TCPServer,您将不得不等待连接超时才能再次运行您的服务器。

关于python - 在单线程 Python 应用程序中关闭 socketserver serve_forever(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10085996/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com