2015-12-21 124 views
0

我正在Python中实现一个协议,以便一个程序发送数据到另一个。它使用结构来获取数据。我无法理解如何在发件人决定发送不同尺寸的邮件时使用包和解包。当它不知道接收包中的数据大小是多少时,接收器如何在它使用unpack之前知道不初始化该结构? 在发送方,我有:Python结构未知大小

values = (numOfPackage, data) 
st = struct.Struct('I 502s') 
packed_data = st.pack(*values) 

和接收端的作用:

packed_data = s.recv(506) 
while packed_data != "": 
     st = struct.Struct('I 502s') 
     unpacked_data = st.unpack(packed_data) 
     print unpacked_data[1] 
     packed_data = s.recv(506) 

但后来我想发送短消息,如“我完成了”从发送端到接收端..但接收者怎么会知道不要做st = struct.Struct('I 502s'),因为它实际上是10s而不是502s?

回答

0

由于接收到的量是每一次相同的,可以只切下来确定所述实际长度后:

st = struct.Struct('I 502s') 
packed_data = s.recv(st.size) 
while packed_data: 
    length, data = st.unpack(packed_data) 
    data = data[:length] 
    print data 
    packed_data = s.recv(st.size) 

可替代地,使用较短的Struct解析长度只,然后手动切出位你对护理:

st = struct.Struct('I') 
packed_data = s.recv(506) 
while packed_data: 
    length, = st.unpack_from(packed_data) # Ignores trailing data using unpack_from 
    data = packed_data[st.size:st.size+length] 
    print data 
    packed_data = s.recv(506) 
+0

我想你的第一个解决方案,但它仍然是problematic..I做: 'ST = struct.Struct(' II 502S') packed_data = s.recv(st.size) 而packed_data = “”: pckNum,长度,数据= st.unpack(packed_data) 数据=数据[:长度] 打印数据 packed_data = s.recv(st.size)' 和它说: struct.error:unpack需要一个字符串参数长度为510 当我尝试发送一条较短的消息 – Shirli

+0

@Shirli:你为什么使用'II 502s'作为格式?你原来的帖子说格式是'我502s'。如果您使用我的第一个解决方案,发送和接收'Struct'的格式应该是相同的;即使只发送“我完成”,它仍然会发送506个字节,并且接收方会收到所有这些字节,然后切片到只发送有意义的字节数。 – ShadowRanger

+0

@Shirli:旁注:如果'Struct'的大小永远不变,请不要在你的循环中创建它;在循环外生成一次,然后重新使用它。如果你每次都重新创建它,你最好不要使用'Struct',而只是使用模块级别的函数; struct.Struct唯一的优点是它可以根据需要为你创建和缓存Struct对象;每个用户手动创建它们是最慢的解决方案(因为它绕过了模块级功能使用的'Struct'缓存)。 – ShadowRanger