Search code examples
csocketsnetwork-programmingudp

How to send a struct over UDP and receive on the other side?


I have a very specific question on socket programming. My code is similar to the following.

struct data_packet{
   unsigned char seqnumber; 
   char data[500]; 
}

struct data_packet packettosend; 
packettosend.seqnumber = '0'
packettosend.data = 'some binary data' (this could be any length from 0 bytes to 500 bytes) 

//sender code 
char buffer[501]; 
memcpy(buffer, &packettosend, sizeof(packetosend)); 
int s = sendto(socketfd, buffer, sizeof(buffer), 0 , .......other params); 

//receiver code
char recvbuffer[501];
int t = recvfrom(recvsocketdf, recvbuffer, 501, 0 ....other params);
  
How do I set up my receiver to receive the data and save it on a `struct data_packet`?    

The seqnumber is a 1-byte char, and data could be 0 byte to 500 bytes.

I am using sendto to send the buffer and recvfrom to receive the buffer on the other end.

How do I receive my seqnumber and data on the receiving end? I am very new to C and Socket programming. I appreciate any help.


Solution

  • Possible problem:

    Code likely writes outside its bounds due to struct padding.

    struct data_packet{
       unsigned char seqnumber; 
       // There maybe padding here.
       char data[500]; 
       // There maybe padding here.
    }
    
    struct data_packet packettosend; 
    char buffer[501];  // May be too small for `packettosend`
    memcpy(buffer, &packettosend, sizeof(packetosend)); 
    

    Alternative: Make buffer[] certainly big enough

    // char buffer[501];
    char buffer[sizeof packetosend];
    

    To send just the data and not certainly not any padding:

    Pack the data with an implementation specific keyword (if available)

    // struct data_packet{
    packed struct data_packet{
    

    Or perform 2 sends

    int s1 = sendto(socketfd, &buffer.seqnumber, sizeof buffer.seqnumber, ...);
    int s2 = sendto(socketfd, buffer.data, sizeof buffer.data, ...);
    

    Or copy carefully

    #define SEQ_DATA (sizeof buffer.seqnumber + sizeof buffer.data)
    char buffer[SEQ_DATA]; 
    memcpy(buffer, &buffer.seqnumber, sizeof buffer.seqnumber);
    memcpy(buffer + sizeof buffer.seqnumber, buffer.data, sizeof buffer.data);
    int s = sendto(socketfd, buffer, sizeof buffer, ...);
    

    Adjust recvbuffer[] size to match.