Предположим, что ваша программа уже организована, чтобы иметь заголовок в одном struct
и данные в другом struct
. Например, у вас могут быть следующие структуры данных:
#include <stdint.h>
struct header {
uint16_t f1;
uint16_t f2;
uint32_t f3;
};
struct data {
uint16_t pf1;
uint64_t pf2;
};
Давайте назовем эту организацию "формат хоста". Мне действительно не важно, какой у вас формат хоста, если он полезен для остальной части вашей программы. Давайте назовем формат, который вы передадите send()
, вызовом «сетевой формат». (Я выбрал эти имена, чтобы они соответствовали именам htons
(от хоста к сети) и htonl
(от хоста до сети).)
Вот некоторые функции преобразования, которые могут оказаться полезными. Каждый из них преобразует ваши структуры формата хоста в буфер сетевого формата.
#include <arpa/inet.h>
#include <string.h>
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]) {
htonHeader(h, buffer+0);
htonData(d, buffer+8);
}
Чтобы отправить свои данные, сделайте это:
...
char buffer[18];
htonHeaderData(myPacketHeader, myPacketData, buffer);
send(sockfd, buffer, 18, 0);
...
Опять же, вам не нужно использовать структуры header
и data
, которые я определил. Просто используйте все, что нужно вашей программе. Ключевым моментом является то, что у вас есть функция преобразования, которая записывает все данные с четко определенными смещениями, в четко определенном порядке байтов в буфер и передает этот буфер в функцию send ().
На другой стороне сетевого соединения вам понадобится программа для интерпретации полученных данных. На этой стороне вам нужно написать соответствующие функции (ntohHeader
и т. Д.). Эти функции будут memcpy
выводить биты из буфера в локальную переменную, которую она может передавать в ntohs
или ntohl
. Я оставлю эти функции на ваше усмотрение.