我正在使用Python中的简单HTTP服务器。我从这里获取点点滴滴:http://hg.python.org/cpython/file/3.3/Lib/socketserver.py看看Python的标准库如何处理它。
我的问题是,一旦我尝试接受请求,我的程序就会挂起。这是我的代码只有100行,所以我直接在这里发布。
我有一个process()函数,它在循环中永远循环,并且它假设处理新的连接。在里面我有一个只打印一次的打印声明。
在TCPServer.process()
中打印('处理')我试过线程关闭process(),但我得到了相同的结果。
"""."""
import socket
import select
from abc import abstractmethod, ABCMeta
class BaseServer(metaclass=ABCMeta):
def __init__(self, server_address, server_port, RequestHandlerClass):
self._server_address = server_address
self._server_port = server_port
self._RequestHandlerClass = RequestHandlerClass
self._running = False
def serve_forever(self):
self._running = True
while self._running:
self.process()
@abstractmethod
def process(self):
pass
def shutdown(self):
self._running = False
class TCPServer(BaseServer):
def __init__(self,
server_address,
server_port,
RequestHandlerClass,
address_family=socket.AF_INET,
socket_type=socket.SOCK_STREAM,
request_queue_size=1,
bind=True):
super(TCPServer, self).__init__(server_address,
server_port,
RequestHandlerClass)
self._address_family = address_family
self._socket_type = socket_type
self._request_queue_size = request_queue_size
self._socket = socket.socket(self._address_family, self._socket_type)
self._read_list = [self._socket]
if bind:
self.bind()
def bind(self):
self._socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self._socket.bind((self._server_address, self._server_port))
self._socket.listen(self._request_queue_size)
def shutdown(self):
super().shutdown()
self._socket.close()
def process(self):
print('processing')
readable, writeable, errored = select.select(self._read_list, [], [])
for socket in readable:
if socket is self._socket:
client_socket, client_address = self._socket.accept()
self._read_list.append(client_socket)
print('connection from: ', client_address)
else:
self._RequestHandlerClass(client_socket)
self._read_list.remove(client_socket)
class BaseRequestHandler(metaclass=ABCMeta):
def __init__(self, client_socket):
self._client_socket = client_socket
self.setup()
try:
self.handle()
finally:
self.finish()
@abstractmethod
def setup(self):
pass
@abstractmethod
def handle(self):
pass
@abstractmethod
def finish(self):
pass
class HTTPRequestHandler(BaseRequestHandler):
def setup(self):
print('REQUEST SETUP')
print(self._client_socket.recv(2048))
def handle(self):
print('REQUEST HANDLE')
def finish(self):
print('REQUEST FINISH')
self._client_socket.close()
if __name__ == '__main__':
tcp_server = TCPServer(server_address='',
server_port=9000,
RequestHandlerClass=HTTPRequestHandler)
tcp_server.serve_forever()
答案 0 :(得分:3)
我运行了你的代码但却无法挂起。但是,process()
函数中存在致命错误,您在client_socket
分支中引用了else:
,但此时未定义client_socket
。你可能想要引用socket
。
我能够在端口9000上与服务器建立两个连接,并为每个连接获得“连接:”行。只要其中一个连接发送了某些内容,您的服务器就会因上述原因而崩溃。