在c - socket编程中发送和接收结构

时间:2014-10-14 19:02:59

标签: c sockets struct network-programming send

我有一个结构定义如下:

struct controlMessage
{
   struct iphdr cmIphdr; //this use ip.h fronm linux library
   struct ipPayload cmIpPayload;
};

struct ipPayload
{
  uint8_t mType;
  uint16_t cid;
  char* payload; //this is intended to send different size of content
}

然后发件人将设置结构并将controlMessage发送到接收器

 struct controlMessage *cMsg = (struct controlMessage*) malloc (sizeof(struct controlMessage);
 cMsg->cmIphdr.protocol = 200; //this is not important, could be any number
 //etc wth all the other fields in iphdr
 //My question is in the ipPayload struct
 cMsg->cmIpPayload.mType = 82; //this is fine
 cMsg->cmIpPayload.cid = 1; //this is fine

 //Now I want to point my char pointer to a struct and send it as content
 struct controlMsg_payload
 {
   uint16_t somePort;
   //will be more stuffs, but keep it 1 for now for simplicity
 }
 struct controlMsg_payload *payload = (struct controlMsg_payload*) malloc(sizeof(struct controlMsg_payload));
 payload->somePort = 1000; //just assign a static number to it

 cMsg->cmIpPayload.payload = (char*) payload; //not sure if i did it right

 //Now sends it using sendto
 data = sendto(sockfd, cMsg, sizeof(struct controlMessage), 0, (struct sockaddr*) &rcv_addr, sizeof(rcv_addr));
 //remove error check for simplicity

我不确定我是否正确发送,但在接收方,我可以正确检索所有信息,除了struct controlMsg_payload中的somePort信息。

以下是接收方的代码

char* buf = malloc(sizeof(struct controlMessage));
data = recvfrom(sockfd,buf,sizeof(struct controlMessage), 0, struct (sockaddr*) &serv_addr, &serv_len);

 struct iphdr* ip_hdr;
 struct ipPayload* ip_payload;

 ip_hdr = (struct iphdr*) buf;
 ip_payload = (struct ipPayload*) (buf+sizeof(struct iphdr));
 //from here I can print mType and cid correctly from ip_payload and also src & dest IP addr from ip_hdr

 //The only information I did not get correctly is the somePort info below
 struct controlMsg_payload* rcv_load;
 rcv_load = (struct controlMsg_payload*) ip_payload->payload; //get this from the struct ipPayload and cast it as it is char* type, not sure if I did it right
 printf ("my port = %d\n",rcv_load->somePort); //WRONG, not = 1000

我很抱歉很多代码,因为没有代码很难解释。基本上,我不会在接收方那边读取某些东西= 1000。

为了测试目的,我在发送方尝试了相同的最后三行(在接收方),我能够读回1000.所以我认为它必须是我打包数据的方式和通过导致此问题的网络发送/接收它。

你能帮我看看吗?提前谢谢!

2 个答案:

答案 0 :(得分:1)

您正在发送指向有效负载的指针,而不是有效负载本身。有效载荷指针在接收器侧没有任何意义。 您需要将有效负载中的所有数据发送到接收器才能使其正常工作。

答案 1 :(得分:1)

使用Wireshark查看您实际发送给另一方的内容。一旦看到正确的数据,就可以开始调试接收器了。在这种情况下,您只发送标头,而不发送有效负载。

/* This sends the header... */
data = sendto(sockfd, cMsg, sizeof(struct controlMessage), ...

发送标题后,您需要发送有效负载。

sendto(sockfd, payload, sizeof(struct controlMsg_payload), ...

标头中指向有效负载(char* payload;)的指针对接收方毫无意义。如果您希望sendto函数跟随指针并发送有效负载,那么它的工作原理并非如此。 sendto实际上只是发送指针的值。

您可以发送指针,只是在接收器上忽略它,或者更好的是你根本无法发送它。