如何在Python套接字中接收和组装可变长度的字节数组?

2024-03-28 20:52:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图将Protobuf类的大字节数组从Java客户机发送到Python服务器。但是,它们有一个变量长度,因为有时我从ClassA发送对象的字节,有时从ClassB发送。在

我有一个Python套接字服务器,在侦听套接字的函数中包含以下代码:

byte_array = bytearray()

# receive the data in small chunks and print it
while True:
    data = connection.recv(64)
    if data:
        # output received data
        logger.debug("Data: %s" % data)
        byte_array.extend(data)

    else:
        # no more data -- quit the loop
        logger.debug("no more data.")
        break

logger.info("Generating response...")
connection.send(generate_response(byte_array))
logger.info("Sent response.")

我正在组装接收到的大字节数组,方法是在获取64个字节时将它们放在一起。在

但是,当字节数组被完全传输并且没有剩余的东西要发送时,服务器挂在connection.recv行上。在

我读到这是因为recv阻塞,直到它接收到某个东西或者连接关闭。但是,我不想关闭连接,因为我想在处理完整个字节数组之后将响应发送回客户端。在

我想知道我接收的字节数组何时已完全传输,这样我就可以避免这种阻塞。在

我可以想出三种选择:

  • 设置一个预定义的“结束”字节,限定字节数组的结尾。在
  • 预先发送字节数组的大小,然后用while True代替while bytes_read < expected_bytes循环。在
  • 在连接上设置一个超时,我假设当超时发生时,意味着所有的东西都已经发送了。在

我倾向于选择第一个选项,但是我不知道应该使用什么字符来结束字节数组,也不知道如何在Python代码中读取它。在

有什么建议吗?在

谢谢。在


Tags: the代码debug服务器truedata字节response
2条回答

选项1:

所以对于第一个选项,您可以设置end byte,它不会出现在实际消息中的任何地方。 您可以为例如“END”创建一个字符串,并将其转换为字节数组并通过java程序发送。接收后,可以使用decode()将其转换为字符串并进行比较。公司名称:

注意:要发送的结束字节必须小于或等于要解码的块的大小,并获得确切的结束字节。在

byte_array = bytearray()

# receive the data in small chunks and print it
while True:
    data = connection.recv(64)
    command = data.decode()
    if command != "END":
        # output received data
        logger.debug("Data: %s" % data)
        byte_array.extend(data)

    else:
        # no more data   quit the loop
        logger.debug("no more data.")
        break

logger.info("Generating response...")
connection.send(generate_response(byte_array))
logger.info("Sent response.")

选项2:

对于第二个选项,您需要修改while循环以根据元数据运行。我考虑过元数据将由第一个块组成,它将是发送。它可能会像:

字节数组=bytearray()

^{pr2}$

选项3:

如果您确定不会有网络延迟,并且唯一的问题是您的java程序必须等待来自python服务器的响应,直到超时发生

选项4:

您可以使用一个非阻塞套接字,它将一直运行到它在预定的时间段内无法接收。虽然我不推荐你的情况下,你可以看看它是否适合你的需要。在

我个人会选择第二种选择(加上合理的超时时间,以满足只发送一半文件并永远挂在那里的恶意客户端的需要)。如果您可以绝对保证它在流中是唯一的,那么分隔字符是很好的(但是您仍然需要超时)。在

如果您不能保证您的分隔符是唯一的,那么发送客户端需要的大小就可以解决问题。如果元数据填充到固定长度,则不需要担心分隔符和检测分隔符。在

相关问题 更多 >