【发布时间】:2020-03-30 11:51:15
【问题描述】:
我正在尝试使用 asyncio 制作一个简单的自制 localhost TCP 服务器(它只有 Python 3.6.9,因为我在这台机器上只有一个 LTS Ubuntu):
import asyncio
import socket
import urllib.parse
from http.server import BaseHTTPRequestHandler
from io import BytesIO
class HTTPRequest(BaseHTTPRequestHandler):
def __init__(self, request_text):
self.rfile = BytesIO(request_text)
self.raw_requestline = self.rfile.readline()
self.error_code = self.error_message = None
self.parse_request()
rpc_request = urllib.parse.urlparse(self.path)
self.endpoint = rpc_request.path
self.query = urllib.parse.parse_qs(rpc_request.query)
def send_error(self, code, message):
self.error_code = code
self.error_message = message
class Srv(asyncio.Protocol):
def __init__(self, address=('127.0.0.1', 12345), family=socket.AF_INET, loop: asyncio.AbstractEventLoop=None):
self._address = address
self._family = family
self._loop = loop if loop is not None else asyncio.get_event_loop()
self._server = None
def connection_made(self, transport):
self._transport = transport
def data_received(self, data):
request = HTTPRequest(data)
print("\tQuery:", request.query)
self._transport.write(b'Hi!')
self._transport.close()
def eof_received(self):
pass
def factory(self):
return self
async def run(self):
sock = socket.socket(family=self._family)
sock.bind(self._address)
sock.listen()
if self._family == socket.AF_UNIX:
self._server = await self._loop.create_unix_server(protocol_factory=self.factory, sock=sock)
else:
self._server = await self._loop.create_server(protocol_factory=self.factory, sock=sock, family=self._family)
self._running = True
omg = Srv()
async def wat():
await omg.run()
await omg._server.wait_closed()
try:
asyncio.get_event_loop().run_until_complete(wat())
except:
omg._server.close()
好像启动,甚至接收数据:
$ python3 0_o.py
Query: {'data': ['"abcd"']}
Query: {'data': ['"abcd"']}
(打印来自Srv.data_received),但 curl 说它没有收到任何回复:
$ curl '127.0.0.1:12345/query?data="abcd"'
curl: (52) Empty reply from server
$ curl '127.0.0.1:12345/query?data="abcd"'
curl: (52) Empty reply from server
从我的角度来看,我已经重新实现了 python 的 stdlib 文档中的 echo 服务器示例中的所有内容,但显然 data_received() 中的 write() 和 close() 似乎没有产生任何效果。
我错过了什么?
【问题讨论】: