天天看點

Socket傳輸結構體資料注意事項

【1 背景】

在Socket通信中,要傳輸結構化的資料或者要進行協定資料傳輸的時候,發送端必須要構造結構體進行資料傳輸。

接收端也必須通過同樣的結構體進行解析。

但Socket傳輸結構體資料時候,稍有不慎就會出現:1)解析資料出錯;2)接收資料不完整;3)解析為亂碼等的Bug。

【2 舉例】

如下是接收端解析資料為亂碼甚至崩潰的一類常見錯誤。

結構體也就是一段連續的記憶體。 但是類似如下的結構體:

typedef struct _PER_SPIDER_INFO
{
UINT nTimeDelay; 
UINT nRtnCode; 
UINT nUrlPageLen; 
char* pszUrlPage; 
}PER_SPIDER_INFO;           

不能直接通過傳輸的。

【3 根本原因】

如下:

1)結構體成員pszUrlPage是指針,指向的是結構體以外的記憶體位址,也就是在結構體PER_SPIDER_INFO外的非連續的位址空間。

2)如果僅傳輸pszUrlPage,也就是傳輸了一個位址,在目前程序空間是可以索引到對應的值。但是一旦通過Socket實作網絡傳輸,即出現了跨程序、跨網絡的傳輸,一個位址傳輸過去,極大可能甚至100%會讀到我們不想要的位址空間,讀取的值也會出錯。一旦該位址空間不允許讀,則會導緻程式崩潰。(如下圖所示)

3)可以傳輸,正如2)所說,但一旦接受後對方機器無法正确解析,甚至程式崩潰。

Socket傳輸結構體資料注意事項

【4 Bug解決步驟路演】

Step1: 縮小範圍,隻傳輸int資料,ok;但單包含了字元串指針就不可以;基本鎖定是字元串這裡除了問題。

Step2:字元串指針換成字元串數組,Bug不再出現。說明至少是連續記憶體這裡出了問題。期間,懷疑動态配置設定記憶體malloc()以及strcpy,memcpy,傳輸結構體資料的長度出了問題,花了近3個小時排查。

Step3:進而換成給定長度(大小結合項目定)的字元串數組,Bug解決掉。

【5 修正後】

typedef struct _PER_SPIDER_INFO
{
UINT nTimeDelay; 
UINT nRtnCode; 
UINT nUrlPageLen; 
char szUrlPage[MAX_URL_PATH]
}PER_SPIDER_INFO;           

就可以通過socket傳輸了。 

【6反思與思考】

但是不是包含指針的就不能傳輸了呢?不是的,隻要記憶體處理的得當也是可以的。回頭有示例再附上解析。

未完待續。

作者:銘毅天下

轉載請标明出處,原文位址:

http://blog.csdn.net/laoyang360/article/details/47342541

繼續閱讀