python-asyncio - ConnectionResetError('连接丢失')python异步服务器
问题描述
我正在为连接在端口 9000 上的 redis 客户端编写一个 redis 服务器(使用 redis-py)。
我现在写了一个简单的测试代码来检查服务器是否正在接收客户端的命令。我的代码如下:
客户端.py
import redis
r = redis.Redis(
host="127.0.0.1",
port=9000
)
v = r.set('foo', 1)
print(v)
v = r.set('bar', '1')
服务器.py
import asyncio
HOST = "127.0.0.1"
PORT = 15000
async def exo_redis(reader, writer):
try:
while True:
data = await reader.readuntil(b'\r\n')
# data = await reader.read(1024)
if not data:
break
print("Data: ", data)
response = "+OK\r\n"
writer.write(response.encode())
await writer.drain()
writer.close()
except asyncio.streams.IncompleteReadError:
pass
def start_server():
loop = asyncio.get_event_loop()
coro = asyncio.start_server(exo_redis, HOST, PORT)
server = loop.run_until_complete(coro)
print("Serving on ", HOST, "port: ", PORT)
try:
loop.run_forever()
except KeyboardInterrupt:
print("\nShutting Down Server...\n")
finally:
server.close()
loop.run_until_complete(server.wait_closed())
loop.close()
if __name__ == '__main__':
start_server()
运行此程序后,我得到的输出有以下异常:
Data: b'*3\r\n'
Data: b'$3\r\n'
Data: b'SET\r\n'
Data: b'$3\r\n'
Data: b'foo\r\n'
Task exception was never retrieved
future: <Task finished coro=<exo_redis() done, defined at app.py:13> exception=ConnectionResetError('Connection lost')>
Traceback (most recent call last):
File "app.py", line 23, in exo_redis
await writer.drain()
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/streams.py", line 348, in drain
await self._protocol._drain_helper()
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/streams.py", line 202, in _drain_helper
raise ConnectionResetError('Connection lost')
ConnectionResetError: Connection lost
Data: b'*3\r\n'
Data: b'$3\r\n'
Data: b'SET\r\n'
Data: b'$3\r\n'
Data: b'bar\r\n'
Data: b'$1\r\n'
Data: b'1\r\n'
出于某种原因,从客户端发送的第一个命令会引发异常,但第二个不会。
如果我使用 reader.read(1024) (在代码中注释),我会得到以下输出:
Data: b'*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$1\r\n1\r\n'
Data: b'*3\r\n$3\r\nSET\r\n$3\r\nbar\r\n$1\r\n1\r\n'
这有时有效并且没有抛出异常,但有时我在命令未完全读取的情况下收到此异常。关于如何纠正这个问题的任何想法,我可以确保在服务器端接收到整个命令?
解决方案
推荐阅读
- azure - OAUTH / Azure Functions:为不支持服务主体的端点验证 AAD 用户的方法
- java - Spring Boot Test:为每个单元测试注入不同的资源
- python - 无法为堆积条形图设置标签
- javascript - Chrome 中的菜单中断
- arrays - Powershell:如何将 -Split 单词数组通过管道传输到命令字符串中
- symfony - 在奏鸣曲编辑选项卡中编写基本 HTML
- c# - 我已在数据网格中启用拖放,但未触发事件处理程序
- python - 从交叉验证绘制 ROC 曲线
- c# - Unity 控制台在按下播放时不显示调试
- java - SQLExceptionjava.sql.SQLException: ORA-28040: 没有匹配的身份验证协议