python - 为什么我的 Python 服务器不能使用 select.select() 同时处理来自多个客户端的数据?
问题描述
我正在尝试制作一个服务器,它可以在 Python 中同时从多个客户端接收和解压缩结构对象。该程序在只有 1 个客户端连接到服务器时工作,但在连接超过 1 个客户端时会产生 struct.error。
就好像这 2 个客户端会将他们的数据作为一个发送,从而创建一个对于 struct.unpack() 大小错误的对象。
服务器端代码:
def handleConnections(self):
while self.inputs:
try:
readable, writeable, exceptional = select.select(self.inputs, self.outputs, self.inputs, self.timeout)
if not (readable or writeable or exceptional):
continue
self.handleInputs(readable, writeable)
except KeyboardInterrupt:
print("Never liked you anyway")
sys.exit()
def handleInputs(self, readable, writeable):
for sock in readable:
if sock is self.server:
self.handleNewConnection(sock)
else:
self.handleQuestionFromClient(sock, writeable)
def handleQuestionFromClient(self, client, writeable):
question = client.recv(1024)
self.respondToClient(question, writeable)
def respondToClient(self, question, writeable):
question = struct.unpack("ci", question)
print("recieved question: ", question)
# Do more stuff
我希望每个客户端都独立地将这些结构对象发送到服务器,然后服务器独立地解包并使用它们。但是,当有 2 个或更多客户端时,我得到这个 struct.error 导致 struct.unpack() 方法接收到错误大小的参数。
Traceback (most recent call last):
File "C:\Users\Dell\Bonus\2019.osz_Telekommunikacios_halozatok\barkoba\server.py", line 104, in <module>
barkobaServer.handleConnections()
File "C:\Users\Dell\Bonus\2019.osz_Telekommunikacios_halozatok\barkoba\server.py", line 95, in handleConnections
self.handleInputs(readable, writeable)
File "C:\Users\Dell\Bonus\2019.osz_Telekommunikacios_halozatok\barkoba\server.py", line 33, in handleInputs
self.handleQuestionFromClient(sock, writeable)
File "C:\Users\Dell\Bonus\2019.osz_Telekommunikacios_halozatok\barkoba\server.py", line 83, in handleQuestionFromClient
self.respondToClient(question, writeable)
File "C:\Users\Dell\Bonus\2019.osz_Telekommunikacios_halozatok\barkoba\server.py", line 44, in respondToClient
question = struct.unpack("ci", question)
struct.error: unpack requires a buffer of 8 bytes
我无法理解为什么此代码适用于单个客户端但在同时连接两个或多个客户端时会失败。
(我不确定我提供的代码是否足够,这是我在 StackOverflow 上的第一个问题)
解决方案
你执行
question = client.recv(1024)
然后假设您可以到达八个字节unpack()
。
稍作调试很快就会发现,在您的两个连接中,一个接收一个或多个字节,另一个接收零字节。
拆开零字节会让你难过。测试长度小于八。
推荐阅读
- android - 不能将 == 与 livedata 一起使用
和 int,我还能如何检查? - python - 删除 over powershell windows 10 Apps
- r - 如何根据另一列的数值创建新列
- r - 如何将列值的下半部分移动到新创建的列中?
- flutter - 从另一个列表中获取项目的索引
- reactjs - 自定义钩子的反应目的
- firebase - 在flutter中找不到providerinstaller的本地模块描述符类
- css - 按钮上类似 3D 的悬停效果
- python - 使用 Python 压缩选择的 PDF 文件 - 减小大小
- java - 为什么 volatile 静态变量不刷新?