我正在编写一个程序,用于使用 Python 进行两个机器人之间的通信,如果有人知道它,项目 Skynet。在写的时候,我遇到了这个问题
File "C:\Users\achau\Desktop\Uni\Fundamental of Sec\Project\part1\skynet_intro\lib\comms.py", line 87, in recv
unpacked_contents = struct.unpack('H', pkt_len_packed)
struct.error: unpack requires a bytes object of length 2
奇怪的是代码第一次总是有效,但第二次我输入一条消息时,它就变成了这样。有谁有想法吗?这是那行代码
def recv(self):
# Decode the data's length from an unsigned two byte int ('H')
pkt_len_packed = self.conn.recv(struct.calcsize('H'))
unpacked_contents = struct.unpack('H', pkt_len_packed)
pkt_len = unpacked_contents[0]
最佳答案
我假设你的 conn
是一个 socket 。 socket.recv(n)
返回最多 n 个字节,但不保证有 n 个字节。只是一个猜测,但可能是您的 recv 只返回一个字节。
检查pkt_len_packed
的长度是多少在调用 struct.unpack()
之前在上面。它可能只是一个。
一个非常典型的套接字编程错误是假设套接字传递消息。他们没有,他们提供数据并且完全不知道其格式、长度、内容和其他类似的东西。如果并且当您接收消息时,您需要从数据流中解析消息。如果您打算发送 2 个字节,则完全有可能在您调用 recv() 时只发送了一个字节,而您只会收到那个。然后,您需要存储刚刚收到的内容并继续接收,直到您拥有所需的一切。如果您的套接字已经包含多条消息,并且您调用 recv 的长度大于队列中第一个消息的长度,那么您也会从一条或多条连续消息中接收数据。如果您现在丢弃此数据,您将丢失消息或消息的一部分,或两者兼而有之。
另一种可能性是您传输 N 个字符,但有一个尾随换行符或另一个终止符。例如,如果您构建了一个消息传递协议(protocol),该协议(protocol)首先传输数据长度,然后传输实际消息,但是您将长度和带有尾随字符的消息字符串写入套接字,那么您的接收器将与您的第一条消息正常工作.它将收到长度,请调用 recv()
在那个长度上,你会认为一切都很好。但是还有一个字节要从套接字读取(换行符?,终止零?),当你现在尝试调用 recv()
再次获取第二条消息的两个字节长的消息长度,实际上您只是收到了您应该作为第一条消息的一部分阅读的尾随终止符,或者根本不发送。这只是猜测,但这些错误非常普遍。
这就是为什么您应该使用对消息进行操作的更高级别的接口(interface)(ZeroMQ 会这样做),或者将套接字操作与消息处理分开,并在对套接字执行任何操作之前验证您从套接字接收的所有内容,以确保您拥有所有您需要的数据。您还需要知道您实际写入套接字的内容并确保您接收到您发送的所有不可见字符。如果您收到的信息超出您的预期,您需要保留剩余部分并继续累加,直到出现完整的信息。
关于python - 结构错误 : unpack requires a bytes object of length 2 on the second input of the program,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46366001/