[英]Passing structure over TCP socket in C
我正在用C編寫一個小型客戶端服務器應用程序。
在客戶端我有一個結構,如,
#pragma pack(1) // this helps to avoid serialization while sending over network.
typedef struct _viewBoxClient_Info
{
unsigned long viewBoxID;
int bRT_flag;
int nFrameNum;
char frameData[1000];
}viewBoxClient_info_send ;
#pragma pack(0) // turn packing off
並填充變量,
struct _viewBoxClient_Info client_info;
client_info.bRT_flag= 10;/*0 for false, 1 for true*/
client_info.viewBoxID=10000;
memcpy(client_info.frameData,buf,sizeof(client_info.frameData)); //char buf[] data is "is 1st line"
client_info.nFrameNum=1;
並使用以下功能發送到服務器,
send(sock, (char *)&client_info, bytesRead, 0);
在服務器端,我有一個結構(與客戶端結構相同),
#pragma pack(1) // this helps to avoid serialization while sending over network.
typedef struct _lclviewBoxClient_Info
{
unsigned long viewBoxID;
int bRT_flag;
int nFrameNum;
char frameData[1000];
}viewBoxClient_info_receive ;
#pragma pack(0) // turn packing off
並接收消息並在屏幕上打印,
viewBoxClient_info_receive lcl_viewBox;
ssize_t bytesReceived = recv( *nfd, &lcl_viewBox, sizeof(struct _lclviewBoxClient_Info), 0);
printf("\nlcl_viewBox.bRT_flag:%d\n",lcl_viewBox.bRT_flag);
printf("lcl_viewBox.nFrameNum:%d\n",lcl_viewBox.nFrameNum);
printf("lcl_viewBox.frameData:%s\n",lcl_viewBox.frameData);
服務器屏幕上的O / p,
lcl_viewBox.bRT_flag:1
lcl_viewBox.nFrameNum:1936287860
lcl_viewBox.frameData: is 1st line
我不知道它在我的服務器端發生了什么。 我從客戶端發送10個bRT_flag,在服務器上接收1個。 還從客戶端發送nFrameNum = 1並在服務器上以nFrameNum:1936287860接收。 frameData也在客戶端我發送“這是第一行”,在服務器接收“只是第一行”。 有人會幫助擺脫這個問題嗎?
感謝致敬,
斯里蘭卡
不應該這樣:
send(sock, (char *)&client_info, bytesRead, 0);
是:
send(sock, (char *)&client_info, sizeof( client_info ), 0);
你應該檢查send()的返回值,特別是recv()的返回值 - 無法保證對recv的調用將一次性獲取你的結構。
像這樣發送原始結構是一個非常糟糕的主意。
您必須處理字節順序(字節順序),打包(即使使用#pragma pack
仍然可能存在問題),另一個問題是像'int'這樣的類型的大小可能因平台而異。
我建議像Google Protocol Buffers這樣的序列化庫來幫助你解決這個問題。 如果你仍然想自己做,你需要查找像htonl
這樣的函數將整數類型轉換為網絡字節順序,並開始使用固定大小的原語,如uint32_t
等。
您還應該立即停止發送整個結構,而是編寫幫助函數,如writeClientStruct(int sock,struct client_struct *),它將分別發送每個成員值以避免平台之間的打包問題。
一種解釋是您的客戶端和服務器對“unsigned long”的大小有不同的解釋。 (在不同的機器或不同的編譯器選項上運行,其他是32位和其他64位)。
這可以解釋症狀:
對此進行簡單檢查將檢查sizeof(結構)或sizeof(unsigned long)以查看它們是否匹配。
請參閱Mike Weller的帖子,了解如何正確解決這個問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.