2011-04-18 250 views
0

我正在讀取文件到結構中,然後將它們寫入服務器。 以下是一段代碼:使用tcp套接字發送結構

struct b{ 
uint16_t num; 
char str[10]; 
} x; 
struct a{ 
uint32_t pid; 
char str1[10]; 
char str2[10]; 

} y;

while(fscanf(fp,"%s",buff) != EOF) 
while(1){ 
c = getchar(); 
if (c == '\n') 
break; 

else 
buff[i]= c ; 
i++; 

write(fd, &b,sizeof(b)) 

文本文件格式

  • 喬治
  • 我如何讀取和存儲文件到每個結構?

  • 當我寫一個服務器,它看起來像

  • 寫(FD,&一個,的sizeof(結構A))。 write(fd,& b,sizeof(struct b))? 如何保證正確的填充,字節序

我這是怎麼運行的文件:/a.out IP端口< file.txt的

+0

[發送結構在TCP(C編程)]可能的重複(http://stackoverflow.com/questions/1734819/sending-struct-over-tcp-c-編程) – 2011-04-18 23:26:01

+0

歡迎來到堆棧溢出!在提出新問題之前,請使用搜索。 SO上已經提出了許多問題,您可以立即找到答案。 – 2011-04-18 23:27:20

回答

0

當你說「讀取和存儲文件到每個結構」 ,你能澄清這個問題嗎?

以確保正確的填充和字節序,你必須做兩件事情:

  1. 發送結構一個場一次。這是一個痛苦。由於您將每個結構成員聲明爲uint16_t類型(以及來自該系列),所以sizeof()將在所有平臺上給出相同的答案。

  2. 爲確保排序,您必須使用主機到網絡訂單系列。請參閱:http://www.gnu.org/s/hello/manual/libc/Byte-Order.html

  3. 當你做到這一點,你必須發送時,然後ntohs()(網絡到主機短)接收時使用htons()(主機到網絡短)。對於你的結構的每個成員。

通常人們會忽視這一點;如果兩臺機器都是現代英特爾盒子,這對我們絕大多數人來說都是如此,那麼您可以擺脫發送結構的代碼。但就像你剛纔提到的那樣,這不符合填充和結果!

您也可以使用#pragma pack() GNU指令來指定如何處理填充。如果您可以依賴於您的客戶端和服務器的GNU工具鏈,這將起作用,因爲這不屬於C規範的一部分。

0

不要對結構使用send/recv(套接字)或讀/寫(文件描述符)。實際上保證稍後休息。在其他問題中,結構成員的填充和/或對齊可以根據編譯器,編譯選項和環境而改變。

而是將數據編組爲獨立格式(如文本)併發送該數據。如果兩邊的數據必須完全相同,則將其編碼到基址64並預先設置校驗和。

如果您絕對必須傳輸二進制數據,請記住將每個結構成員轉換爲網絡字節順序(man byteorder)並分別發送每個結構成員。