简体   繁体   English

在C中发送和接收结构-套接字编程

[英]Send and receive struct in c - socket programming

I have a struct defined as follow: 我有一个结构定义如下:

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
}

Then the sender will set up the struct and send the controlMessage to receiver 然后,发送方将设置该结构并将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

I'm not sure if I send it correctly, but in the receiver side, I could retrieve all information correctly, except for the somePort info in the struct controlMsg_payload. 我不确定是否发送正确,但是在接收方,我可以正确检索所有信息,但struct controlMsg_payload中的somePort信息除外。

Below is my code in the receiver side 下面是我在接收方的代码

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

I'm sorry for a lot of codes since it's hard to explain without it. 我为许多代码感到抱歉,因为没有它很难解释。 Basically, I don't read somePort = 1000 back in the receiver side. 基本上,我不会在接收器端读取somePort = 1000。

I tried the same last three lines (in the receiver side) in the sender side for testing purposes, I'm able to read back 1000. So I believe that it has to be the way I package the data and send/receive it over the network that causes this. 为了测试目的,我在发送方尝试了最后三行(在接收方),我能够读回1000。因此,我相信这必须是我打包数据并通过它发送/接收数据的方式导致这种情况的网络。

Could you guys please help me take a look? 你们能帮我看看吗? Thanks in advance! 提前致谢!

You are sending the pointer to the payload, not the payload itself. 您正在发送指向有效负载的指针,而不是有效负载本身。 The payload pointer does not make any sense on the receiver side. 有效负载指针在接收方没有任何意义。 You need to send all data in the payload to the receiver for this to work. 您需要将有效负载中的所有数据发送到接收器,以使其正常工作。

Use Wireshark to look at what you have actually sent to the other side. 使用Wireshark查看您实际发送给另一端的内容。 Once you see the correct data, then you can start debugging your receiver. 一旦看到正确的数据,就可以开始调试接收器。 In this case, you are sending the header only and never sending the payload. 在这种情况下,您仅发送标头,而从不发送有效负载。

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

After sending the header, you need to send the payload. 发送标头后,您需要发送有效负载。

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

The pointer to the payload ( char* payload; ) in the header is meaningless to the receiver. 头中指向有效负载的指针( char* payload; )对接收者而言毫无意义。 If you are expecting the sendto function to follow the pointer and send the payload, that's not how it works. 如果您期望sendto函数跟随指针并发送有效负载,那不是它的工作原理。 sendto is literally just sending the value of the pointer. sendto实际上只是发送指针的值。

You could send the pointer and just ignore it on the receiver, or better yet you could not send it at all. 您可以发送指针而只是在接收器上忽略它,或者更好的是您根本无法发送它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM