Zhi Wang
Zhi Wang

Reputation: 1168

Define structure for network communication in C

I want to define a structure in C for network transferring, for example I want to transfer an Animal structure, which contains a variable length of animal name.

AFAIK, one way is using a predefined length of char array, or using a buffer in the struct, and we can parse the buffer (e.g., the first 4 bytes are the animal name length, followed by the animal name, and other fields' length and other fields' values), the advantage of the latter method is that it allows variable name length, as following code indicates:

struct Animal
{
    char   name[128];
    int    age;
}

or:

struct Animal
{
    int    bufferLen;
    char*  pBuffer;
}

My question is: are my approaches correct? i.e., there are the standard ways to transfer struct, and are there better ways?

My second question is: do I need to pay attention to paddding, i.e., use #pragma pack(push/pop, n)?

Thanks in advance!

Upvotes: 1

Views: 1333

Answers (1)

iabdalkader
iabdalkader

Reputation: 17312

Both work fine, however, if you use a fixed length packed sturct it makes it slightly easier to deal with, but you may send more data than you need, for example, the following code, Assuming a 4 byte integer, will send 132 bytes:

//packed struct
struct Animal {
    char   name[128];
    int    age;
};

Animal a = {"name", 2};
send(fd, &a, sizeof(a), 0);
//and you're done

On the other hand variable length fields will need more work to allocate memory and pack in a single packet, but you will be able to send the exact number of bytes you want, 9 bytes in this case:

//not necessarily packed   
struct Animal {
    char   *name;
    int    age;
};

//some arbitrary length
int name_length = 50;
//you should check the result of malloc
Animal a = {malloc(name_length), 2}; 

//copy the name
strcpy(a.name, "name");

//need to pack the fields in one buff    
char *buf = malloc(strlen(a.name)+ 1 + sizeof(a.age));
memcpy(buf, a.name, strlen(a.name)+1);
memcpy(buf, &a.age, sizeof(a.age));

send(fd, buf, strlen(a.name)+ 1 + sizeof(a.age));
//now you have to do some cleanup
free(buf);
free(a.name);

Edit: This is of course if you want to implement that yourself, you could use a library to serialize the data for you. Also, check the example serialization code in the Beej's Guide to Network Programming

Upvotes: 3

Related Questions