Создание и отправка необработанных пакетов данных в C / Stack Overflow

Я знаю, как выглядит мой пакет. Она имеет 6 поля заголовка (1 байт каждое, каждый заголовок имеет 8 полей), а затем он имеет полезную нагрузку (данные).

Я хотел бы построить необработанный пакет на C или C ++ (он должен выглядеть так же, как я думаю).

Вот что я должен сделать:

    unsigned char packet[11];

packet[0] = (0x81); // first header with 8 fields
packet[1] = (0x8c); // second header with 8 fields
packet[2] = (0xfe);
packet[3] = (0x84);
packet[4] = (0x1d);
packet[5] = (0x79);
packet[6] = (0x96); // payload, the 'h' letter, masked
packet[7] = (0xe1); // 'e'
packet[8] = (0x71); // 'l'
packet[9] = (0x15); // 'l'
packet[10] = (0x91);// 'o'

Где, например, 0x81 это первый байт (я просто преобразовал каждое поле (бит) моего первого заголовка в шестнадцатеричное).

И тогда, просто, я хочу отправить его на сервер: send(sockfd, packet, sizeof(packet), 0) отправить это.

Получение и печать ответа:

unsigned char buffer[1024];
if ((recv(sockfd, buffer, len, 0)) == 0)
{
if (errno != 0)
{
exit(1);
}
}

int i;
for(i = 0; i<len; i++)
printf("%x ", buffer[i]);

Я прав?

-2

Решение

Кроме неправильного обращения с возвращаемым значением из recv, ваш код выглядит хорошо.

if ((recv(sockfd, buffer, len, 0)) == 0)
{
if (errno != 0)
{
exit(1);
}
}

Нулевой возврат указывает на нормальное закрытие соединения. Там нет причин, чтобы проверить errno если он возвращает ноль.

Возвращаемое значение -1 указывает на ошибку. В этом случае имеет смысл проверить errno,

Значение больше нуля указывает, что количество байтов было получено. Помните, что это совершенно нормально для recv вернуть меньше байтов, чем вы просили. Если вы хотите получить определенное количество байтов, вы должны позвонить recv в петле.

TCP является протоколом потока байтов и не знает, где начинаются и заканчиваются ваши «пакеты» (на самом деле, сообщения).

1

Другие решения

Ваш код не будет подвержен ошибкам!

Но хорошей практикой будет:

const std::uint32_t BUFFER_SIZE = 11;

std::vector<std::uint8_t> buffer;
buffer.reserve(BUFFER_SIZE)

buffer = {0x81,0x8c.....};

send( sockfd,
reinterpret_cast <const char*> ( buffer.data() ),
static_cast      <int>         ( buffer.size() ),
0
);

Таким образом, ваш код становится более оптимизированным и избегает возможных утечек, используя std векторы.

Может также извлечь выгоду из взгляда на ZeroMQ, в качестве примера готовой высокопроизводительной библиотеки асинхронных сообщений, предназначенной для использования в распределенных или параллельных приложениях.

0

По вопросам рекламы [email protected]