我正在用Python开发一个简单的HTTP服务器。我从这里获取一些零碎的东西:http://hg.python.org/cpython/file/3.3/Lib/socketserver.py 看看 Python 的标准库如何处理它。
我的问题是,一旦我尝试接受请求,我的程序就会挂起。这是我的代码,它只有 100 行,所以我直接在这里发布它。
我有一个 process() 函数,它处于一个永远循环的循环中,它应该处理新的连接。在里面,我有一个打印语句,只能打印一次。
print('processing') in TCPServer.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()
我运行了你的代码,但无法让它挂起。但是,process()
函数中存在一个致命错误,在该错误中,您在else:
分支中引用client_socket
,但此时未定义client_socket
。您可能打算指socket
.
我能够在端口 9000 上与服务器建立两个连接,并为每个连接获得"连接自:"行。一旦其中一个连接发送了某些内容,您的服务器就会由于上述原因而崩溃。