struct.pack()Python未知字段长度通过套接字发送

时间:2013-10-22 08:09:09

标签: python sockets tcp struct pack

我正在使用Python开发TCP客户端。当我想将结构发送到服务器时,我的问题出现了,我使用方法struct.pack()发送和struct.unpack()接收。我有自己的协议TCP,有一些标题,我已经知道它们的长度,但当然,我不知道身体的长度,我怎么能包装所有字段而不知道身体的长度?这是一个例子:

请求服务器:

pack('!BBBBHHII', P2P_h.version, P2P_h.ttl, P2P_h.msgType, P2P_h.reserved, P2P_h.sendPort, P2P_h.payloadLength, P2P_h.ipSrc, P2P_h.messageId)

来自服务器的响应:

queryHit = unpack ("!BBBBHHII", queryResponse)

在这些例子中,只有标题,我的意思是,我已经知道它们的长度的字段,我怎么能添加正文字段?

1 个答案:

答案 0 :(得分:1)

Python套接字send`recv对字符串进行操作。 通过使用pack,您已经将其他类型(整数,布尔值......)转换为字符串。 假设你的身体只是原始二进制数据 - 一个字符串,那就是 - 你只需要连接你已经拥有它的字符串。此外,由于正文的长度可变,您可能还想在邮件中发送正文大小,以便了解要在recv中阅读的尺寸:

data=pack('!BBBBHHII', P2P_h.version, P2P_h.ttl, P2P_h.msgType, P2P_h.reserved, P2P_h.sendPort, P2P_h.payloadLength, P2P_h.ipSrc, P2P_h.messageId) #your current header
data+= pack("!I",len(body)) #assumes len(body) fits into a integer
data+= body #assumes body is a string
socket.send(data)

要接收,请执行相反的操作:

data= socket.recv( struct.calcsize('!BBBBHHII') )
P2P_h.version, P2P_h.ttl, P2P_h.msgType, P2P_h.reserved, P2P_h.sendPort, P2P_h.payloadLength, P2P_h.ipSrc, P2P_h.messageId= unpack('!BBBBHHII', data)
data= socket.recv( struct.calcsize("!I") )
body_size= unpack("!I", data)
body= socket.recv( body_size )

为了清晰起见,我将体型与其他字段分开,但您可以将它们组合起来。