Python 如何有效地从socket.recv()解包数据?

Python 如何有效地从socket.recv()解包数据?,python,performance,sockets,buffer,slice,Python,Performance,Sockets,Buffer,Slice,我希望在Python中通过指定每次调用后的接收大小来优化socket接收调用。我收到一个6字节的报头(前4个为空,后2个为大端)。我的想法是,通过解压前6个字节,然后使用得到的整数值,将接收缓冲区设置为该特定值,读取套接字并立即将结果添加到列表中,从而获得所需的消息大小。以下是我的代码片段: engine_messages = [] try: while True: size_header = struct.unpack('!4cH', self.iosocket.rec

我希望在Python中通过指定每次调用后的接收大小来优化socket接收调用。我收到一个6字节的报头(前4个为空,后2个为大端)。我的想法是,通过解压前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()
问题是,当我进行测试运行时,它会返回随机结果。有时,我会得到一个包含10项的列表,有时是100项,有时是期望值。当我将接收缓冲区设置为
4096
时,我总是收到正确数量的回复。但在这样做时,我必须
“”。join()
我的列表并执行昂贵的字符串切片以获取行。现在,对于成百上千的结果集来说,这并不是什么大问题。问题是,当我处理一个包含数十万或百万条记录的“合并”列表时,处理时间开始攀升,其中每行大约有2500多个字符

通过直接从流中填充列表,它将增加套接字调用,但不会增加太多,并且总体上会大大节省我的时间。任何想法都将不胜感激


在Python2.7.8/Mac和2.7.8/Linux上运行时,这里的问题是,假设调用总是读取作为参数给定的字节数。事实上,它可能读得比那要少——操作系统网络堆栈缓冲区中在等待应用程序消费时可用的任何东西。这有效地破坏了流中协议消息的对齐

您需要在应用程序级别相应地检查套接字调用和缓冲区返回的大小


注意:您没有指定,但我在这里假设TCP是从异常处理块中提到的“流”开始的。

啊,我看到我的假设让我看起来很傻。不过,您是对的,这是一个TCP流。现在,如果我理解正确的话,添加这个缓冲区检查会增加开销,不是吗?有没有类似的模式?我总是尽我所能做到像蟒蛇一样。进一步思考你的答案,我现在明白了引擎盖下发生了什么。我的逻辑充其量是非常粗略的,需要对缓冲区执行进一步的检查并相应地接收。从我收集到的信息来看,我的套接字逻辑是贪婪的,只是需要更多的仔细检查。真的很喜欢你的回答,让我想得更彻底。我不会考虑做适当的检查来“开销”。您希望您的程序首先是正确的,其次是快速的。坏的缩放快速代码没有实际用途:)当然没有。。你完全正确。我对套接字数据接收的想法有点天真。我将做一些快速的基准测试,然后提供一些颜色。在重新编写代码之后,我能够实现逻辑来正确检查负载大小。我认为听取您的意见并认真思考问题确实帮助我理解并优化了代码。