我希望通过在调用它之后指定接收大小来优化Python中的套接字接收调用。我收到一个6字节的标题(前4个是空白,最后2个是big-endian)。我的想法是通过解压缩前6个字节获得所需消息的大小,然后使用生成的整数值,将接收缓冲区设置为该特定值,读取套接字并立即将结果添加到我的列表中。这是我的代码段:
engine_messages = []
try:
while True:
size_header = struct.unpack('!4cH', self.iosocket.recv(6))[4]
socket_payload = self.iosocket.recv(size_header)
engine_messages.append(socket_payload)
except struct.error:
print 'we received 0 bytes; end of stream'
finally:
self.iosocket.close()
问题在于,当我进行测试运行时,它会返回RANDOM结果。有时候,我会得到一个包含10个项目的列表,有时是100个,有时是预期值。当我将接收缓冲区设置为4096
时,我总是收到正确的回复量。但是这样做,我必须"".join()
我的列表并执行昂贵的字符串切片来获取我的行。现在,这对数百/数千的结果集来说并不重要。问题是当我通过"加入时,处理时间开始攀升。数十万或数百万条记录的列表,每行约2500多个字符。
通过直接从流中填充列表,它会增加套接字调用但不会太多,并且可能会大大节省我整个时间。任何想法都将不胜感激。
在Python 2.7.8 / Mac和2.7.8 / Linux上运行
答案 0 :(得分:1)
这里的问题是你 假设 socket.recv()
调用总是读取作为参数给出的字节数。实际上,它可能会读取 less - 然后在等待应用程序消耗的OS网络堆栈缓冲区中可用的任何内容。这有效地破坏了流中协议消息的对齐。
您需要相应地检查应用程序级别的套接字调用和缓冲区返回的大小。
注意:你没有指定,但我在这里假设TCP在异常处理块中提到“stream”。