Я знаю, как выглядит мой пакет. Она имеет 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]);
Я прав?
Кроме неправильного обращения с возвращаемым значением из recv
, ваш код выглядит хорошо.
if ((recv(sockfd, buffer, len, 0)) == 0)
{
if (errno != 0)
{
exit(1);
}
}
Нулевой возврат указывает на нормальное закрытие соединения. Там нет причин, чтобы проверить errno
если он возвращает ноль.
Возвращаемое значение -1
указывает на ошибку. В этом случае имеет смысл проверить errno
,
Значение больше нуля указывает, что количество байтов было получено. Помните, что это совершенно нормально для recv
вернуть меньше байтов, чем вы просили. Если вы хотите получить определенное количество байтов, вы должны позвонить recv
в петле.
TCP является протоколом потока байтов и не знает, где начинаются и заканчиваются ваши «пакеты» (на самом деле, сообщения).
Ваш код не будет подвержен ошибкам!
Но хорошей практикой будет:
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, в качестве примера готовой высокопроизводительной библиотеки асинхронных сообщений, предназначенной для использования в распределенных или параллельных приложениях.