2015-12-21 122 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