C++和python使用struct傳輸二進制數據結構來實現


網絡編程問題往往涉及二進制數據的傳輸。在C++經常使用的傳輸是文本字符串和分組結構。

假設該數據可以預先送入連續的內存區域,然后讓send函數來獲得的第一個地址,這一塊連續的內存區就能完成傳輸數據。文本字符串,如char排列,字節。中是順序存儲的。所以能夠直接用send函數發送。

可是假設要同一時候發送多個不同類型的數據時,它們在內存中存儲的地址是隨機的,不是順序存儲的,並且它們之間的相對位置也無法確定。這樣就須要一種數據組織方式來明白各數據之間的相對位置。結構體顯然就是一種的數據組織方式,使用結構體要注意數據對齊的問題,關於結構體中數據對齊的問題可參考這篇文章:http://blog.163.com/kan586@126/blog/static/95532454200891191451827/

假設熟悉結構體中數據對齊的規則,能夠合理設計結構體的結構,各成員變量的順序,使得全部的數據成員存放在連續的存儲區。並且結構體的長度等於全部成員長度之和(能夠適當在尾部用字符數組補齊,避免編譯器自己主動填充),這樣就方便用send函數發送了。( 假設server和client都是用C/C++開發,兩端能夠通過相同結構的結構體來封包和解包,能夠不考慮數據對齊的問題)以下討論的是在C++和python開發的兩端之間數據傳輸的情況:client用的C++編寫,server端用python編寫。相對於C++中用struct來封包和解包,python提供了struct庫實現類似的功能,最重要的三個函數是pack,unpack,calcsize,struct庫處理二進制數據的詳細使用方法能夠參考這篇文章:http://www.cnblogs.com/gala/archive/2011/09/22/2184801.html。在python下用socket接收到的字節流實際上是字符串。須要對全部的字節進行指定解析格式,所以在C++發送的時候就要避免發送不確定的數據(如編譯器自己主動填充的數據)。假設用struct組織數據就須要考慮數據對齊的問題了。

以下用一個實例來說明:在C++client有1個a(float) ,1個b(unsigned char),一個c(short) 要發送給server端,在不使用#pragma指令指定編譯器的對齊位數時, 在我的編譯器環境下默覺得4。能夠這樣設計結構體:

struct data
{
      float a;                 //0~3
      short c;                 //4~5
      unsigned char b;         //6
      char extra[2];           //7~8  結構體長度為8字節,這里用字符數組補齊8字節,避免編譯器填充
};
pythonserver端用struct庫來解包。能夠設計例如以下格式:

import struct
...
rdata = s.recv(1024)
a,b,c,d = struct.('fhB2s',rdata)  #a,b,c即需要對數據進行
print a,b,c


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM