Creating and sending data packets in C/C++

Could you expand on what you mean by "all in one packet"? Do you mean the link-layer packets (Ethernet, PPP, etc.)? Or do you mean something else?

Commented Apr 26, 2011 at 20:03

@Rob, well, I would like to not call send() multiple times to send the headers and the data. I would like to send the headers and data together using one single call to send(). Unless this is not how it's normally done?

Commented Apr 26, 2011 at 20:09

That's a fine requirement, @Chad. It's just that "packet" means different things in different contexts, and I wanted to make sure you weren't talking about something else. I've seen programs send the headers and data in one send , 2 send s, and in more than 2 send s. There is no "normal" there, just whatever is convenient to the organization in your code.

Commented Apr 26, 2011 at 20:27

4 Answers 4

Let's suppose that your program is already organized to have the header in one struct and the data in another struct . For example, you might have these data structures:

#include struct header < uint16_t f1; uint16_t f2; uint32_t f3; >; struct data < uint16_t pf1; uint64_t pf2; >; 

Let's call this organization "host format". It really doesn't matter to me what the host format is, as long as it is useful to the rest of your program. Let's call the format that you will pass to the send() call "network format". (I chose these names to match the htons (host-to-network-short) and htonl (host-to-network-long) names.)

Here are some conversion functions that we might find handy. Each of these converts your host format structures to a network format buffer.

#include #include void htonHeader(struct header h, char buffer[8]) < uint16_t u16; uint32_t u32; u16 = htons(h.f1); memcpy(buffer+0, &u16, 2); u16 = htons(h.f2); memcpy(buffer+2, &u16, 2); u32 = htonl(h.f3); memcpy(buffer+4, &u32, 4); >void htonData(struct data d, char buffer[10]) < uint16_t u16; uint32_t u32; u16 = htons(d.pf1); memcpy(buffer+0, &u16, 2); u32 = htonl(d.pf2>>32); memcpy(buffer+2, &u32, 4); u32 = htonl(d.pf2); memcpy(buffer+6, u32, 4); > void htonHeaderData(struct header h, struct data d, char buffer[18])

To send your data, do this:

. char buffer[18]; htonHeaderData(myPacketHeader, myPacketData, buffer); send(sockfd, buffer, 18, 0); . 

Again, you don't have to use the header and data structs that I defined. Just use whatever your program needs. The key is that you have a conversion function that writes all of the data, at well-defined offsets, in a well-defined byte order, to a buffer, and that you pass that buffer to the send() function.

On the other side of the network connection, you will need a program to interpret the data it receives. On that side, you need to write the corresponding functions ( ntohHeader , etc). Those function will memcpy the bits out of a buffer and into a local variable, which it can pass to ntohs or ntohl . I'll leave those functions for you to write.