使用recvfrom()和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,但由于struct hostent包含指针,所以这个struct的成员只要被转移到另一端就没有意义。

我会删除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); 

阅读有关套接字函数的文档总是有帮助的。

顺便说一句,如果我在你的post中考虑非常通用的问题,即“我想从服务器向客户端发送结构”,我建议在SO上查看以下post:

通过C中的套接字传递结构