![](/img/trans.png)
[英]Sockets UDP: Using Sender Info from Recvfrom() in Sendto() Fails
[英]Sending structure using recvfrom() and sendto()
我使用的是C語言 ,它是服務器和客戶端的通用平台 。
我有一個特定類型的結構,我想從服務器發送到客戶端。
例如
服務器代碼
//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);
所以,基本上我想從服務器向客戶端發送一個結構。 但是從上面的代碼中我得到了分段錯誤,我不確定這種結構轉移是否可行。 有什么出路嗎?
首先,您必須使用malloc()以便為struct hostent分配內存。 你可以通過sendto()/ recvfrom()傳遞一個結構,但由於struct hostent包含指針,這個結構的成員只要被轉移到另一端就沒有意義。
我會刪除hp前面的&
通常,您希望避免通過網絡傳輸原始結構,除非它們專門設計用作網絡傳輸,或者除非您絕對確定兩端始終是完全相同的體系結構。 填充和字節排序的差異可能導致數據在另一端出現亂碼。 您嘗試傳輸的特定類型的結構將無法正常發送(請參閱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);
如果hp是指針,為什么要取其地址?
您應該更正代碼,如下所示:
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);
閱讀有關套接字函數的文檔總是有幫助的。
順便說一句,如果我在你的帖子中考慮非常通用的問題,即“我想從服務器向客戶端發送一個結構”,我建議在SO上查看以下帖子:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.