1
votes

I have to send multiple variables types over an udp socket: an int array and a char. I would like to send it on the same udp packet. What is the standard solution? Convert everything to bytes or something similar?

I'm using: sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);

My code is something like:

int buffer[100];
char flag = '0';
int i = 0;

for (i = 0; i < 50; i++) {
    buffer[i] = i * 2;
}

if (sendto(s, buffer, sizeof(buffer), 0, (struct sockaddr *) &si_client, slen) == -1 ){
    //error
}

//rest of the program
2

2 Answers

3
votes

Yes, you need to serialize your message into a byte array. There is no version of sendto that accepts an int array. Try something like this:

int arr[] = {1, 2, 3};
char str[] = "hello";
size_t buflen = sizeof arr + sizeof str;

char* buf = malloc(buflen);
if (NULL == buf)
    abort();
unsigned i = 0;
for (unsigned j=0; j<3; ++j)
{
    buf[i++] = (arr[j] >> 24) & 0x000000ff;
    buf[i++] = (arr[j] >> 16) & 0x000000ff;
    buf[i++] = (arr[j] >>  8) & 0x000000ff;
    buf[i++] = (arr[j] >>  0) & 0x000000ff;
}
strcpy(&(buf[i]), str);

if (sendto(s, buffer, sizeof(buffer), 0, (struct sockaddr *) &si_client, slen) == -1 ){
    //error
}

Note that your message may still be sent as more than one packet, for instance if its size exceeds the path MTU.

0
votes

The usual approach is to put the data in a struct. You can then use the "sendto" call to send the whole struct at once.

Be aware though that this is not entirely portable. Different systems may lay out your struct differently. To reduce the risk of this happening you should.

  • Lay out your structure so that all values are naturally aligned and you do not rely on padding.
  • Use the "htons", "htonl", "ntohs" and "ntohl" macros to convert from host byte order to network byte order and vice-versa when filling in the structure and interpreting it's contents.