2009-08-04 47 views
3

我正在使用C語言這對於服務器和客戶端都是公用平臺使用recvfrom()和sendto()發送結構

我有一個特定類型的結構,我想從服務器發送到客戶端。

例如,

服務器代碼

//necessary declarations 

struct hostent *hp; 

hp=gethostbyname("www.google.com"); 

sendto(sockDes,&hp,sizeof(hp),0,(struct sockaddr *)&cli_addr,sizeof(cli_addr)); 

客戶端代碼

struct hostent *hp; 

msg=recvfrom(mysock,&hp,sizeof(hp),0,(struct sockaddr)&serv_addr,&size_len); 

所以,基本上我想從服務器向客戶端發送的結構。但是從上面的代碼中我得到了分段錯誤,而且我不確定這樣的結構傳輸是否可行。有什麼出路嗎?

+0

這或多或少是。儘管如此,我不會稱之爲便攜式。 – Skurmedel 2009-08-04 19:09:23

回答

6

首先,你必須malloc()以便爲struct hostent分配內存。 你可以通過sendto()/ recvfrom()傳遞一個結構體,但是因爲struct hostent包含指針,所以這個指針的成員只要將它們轉移到另一端就沒有意義。

+1

好抓!我正在尋找段錯誤的原因,甚至沒有想到他究竟是在試圖傳輸什麼。 – 2009-08-04 19:26:25

+1

好吧,發送結構hostent並不重要。如果我將結構字符串的內容按字符串發送到服務器,會更好。 – 2009-08-04 19:51:40

+2

這是正確的,通常情況就是這樣。除非您對此非常小心,否則您確實不希望通過網絡傳輸字符或整數以外的任何內容。而當你傳輸整數時,一定要使用htonl/htons/ntohl/ntohs系列函數將它們轉換爲網絡字節順序。 – 2009-08-04 20:49:43

1

如果HP指針的前面取下&,你爲什麼要採取它的地址嗎?

4

一般而言,您希望避免通過網絡傳輸原始結構,除非它們專門用作網絡傳輸,或者除非您確定兩端始終是完全相同的體系結構。填充和字節排序的差異可能會導致數據在另一端出現亂碼。您試圖傳輸的特定類型的結構只是無法正常發送(請參閱Petros的答案)

您的發送代碼中的問題是,hp是一個指針,並且您正在處理它,就像它是數據它指向。 sizeof(hp)返回指針的大小,而不是指向hostent結構的大小。另外,當你不想要的時候,你正在sendto的第二個參數中創建一個指針指針。發送代碼應爲:

struct hostent *hp; 

hp=gethostbyname("www.google.com"); 

sendto(sockDes,hp,sizeof(*hp),0,(struct sockaddr *)&cli_addr,sizeof(cli_addr)); 

您在接收代碼中也有問題。您應該爲recvfrom分配空間來存儲它收到的數據。它不會爲你分配它。更改接收代碼,這兩個中的一個:

// Store on the stack 
struct hostent h; 

msg=recvfrom(mysock,&h,sizeof(h),0,(struct sockaddr)&serv_addr,&size_len); 

// Store on the heap, be sure to free() when done 
struct hostent * hp = malloc(sizeof(struct hostent)); 

msg=recvfrom(mysock,hp,sizeof(*hp),0,(struct sockaddr)&serv_addr,&size_len); 
1

您應該糾正的代碼如下所示:

struct hostent *p_hp = gethostbyname("www.google.com"); 
struct sockaddr_in cli_addr; 
sendto(sockDes,p_hp,sizeof(hostent),0,(SOCKADDR *)&cli_addr,sizeof(cli_addr)); 


struct hostent hp; 
struct sockaddr_in serv_addr; 
int size_serv_addr = sizeof(serv_addr); 
msg=recvfrom(mysock,&hp,sizeof(hostent),0,(SOCKADDR *)&serv_addr,&size_serv_addr); 

它總是幫助上閱讀文檔套接字功能。