2014-09-13 37 views
0

我正在使用C++在套接字上傳遞一個結構。我閱讀了一些關於發送結構的問題,並且建議在轉換後使用char *進行轉移。由於服務器和客戶端都在同一臺機器上,所以在這裏沒有排序問題。服務器沒有收到C++套接字中的尾部長整數

幾個問題在這裏。我把struct的大小定爲48.根據我的計算,它不應該是43嗎? 8x4 + 10 +1

其次在服務器端,當我打印收到的緩衝區時,我只能得到文本元素。長整數沒有收到。

struct testStruct{ 
    char type; 
    char field1[10]; 
    char field2[8]; 
    char field3[8]; 
    long num1, num2; 
}; 


    testStruct ls; 
    ls.type = 'U'; 

    strcpy(ls.field1, "NAVEENSHAR"); 
    strcpy(ls.field2, "abcd1234"); 
    strcpy(ls.field3, "al345678"); 
    ls.num1 = 40; 
    ls.num2 = 200; 
    char* bytes = static_cast<char*>(static_cast<void*>(&ls)); 
    bytes_sent = send(socketfd, bytes, sizeof(ls), 0); 
    cout << "bytes sent: " << bytes_sent<< "\n"; 

    //On server sidechar 
    incomming_data_buffer[1000]; 
    bytes_recieved = recv(new_sd, incomming_data_buffer,1000, 0); 
    cout << "|" << incomming_data_buffer << "|\n"; 

它顯示48個字節收到,並沒有我添加的尾隨整數。 關於爲什麼會發生這種情況的任何想法。我已經閱讀過關於使用boost序列化發送結構的問題,但同時對於簡單結構來說開銷很大。

+1

'sizeof(testStruct)'是48 [因爲對齊](http://stackoverflow.com/questions/119123/why-isnt-sizeof-for-a-struct-equal-to-the-sum-of -的-各部件-sizeof)。 'long'必須在'sizeof(long)'邊界上對齊,這在你的機器上顯然是8個字節。另一方面,字符只需要對齊1個字節。前四個成員有27個字節,因此編譯器必須在'field3'和'long'之間添加額外的填充(5個字節)以便對齊工作。因此27 + 5字節= 32字節,爲兩個「長」提供了適當的對齊方式(並解釋了5字節的差異)。 – 2014-09-13 07:35:09

+1

還請注意,您的字符串字段對於要複製到的字符串太小 - 顯然,您不允許使用\ 0終止符。將來使用strcpy可以避免你犯這種錯誤時的內存損壞。 – 2014-09-13 07:44:04

+0

@PaulR,\ 0是否必要?我只使用'strcpy'?不明白你的意思。 – 2014-09-13 07:54:58

回答

2

你幾乎肯定會收到所有的數據。問題是與這一行:

cout << "|" << incomming_data_buffer << "|\n"; 

它打印incomming_data_buffer爲C風格字符串,所以停止在第一零字節。由於您的long值以二進制編碼,因此至少會有零(在字段之間填充的位置可能有零)。

你可以嘗試做這樣的事情:

cout << "|"; 
for (int i = 0; i < bytes_received; i++) 
{ 
    cout << hex << (((int)incomming_data_buffer[i]) & 0xff) << " "; 
} 
cout << "|\n"; 

顯示你收到的包的所有字節。

+0

我試過這個,但是得到一些奇怪的cout錯誤,對於運算符<<' – 2014-09-13 11:41:35

+0

,類型爲int和char [2]的無效操作數需要圍繞數學表達式的另一組括號以及&0xff。現在編輯。 – 2014-09-13 17:25:26

+0

我看到所有收到的字節,但我認爲服務器想要很長時間立即開始發佈第三個字段。有沒有辦法實現這一點,並避免填充? – 2014-09-14 06:59:11