Самый простой способ «заглянуть» - просто recv
, а затем recv
еще немного.
Поскольку это, похоже, TCP, вам уже нужен цикл recv
. Цикл recv
всегда необходим с TCP. Когда вы спрашиваете recv(sock, &buf, 16, 0)
, нет гарантии, что вы получите 16 байтов. Если сообщение было разделено на два пакета в отправителе, вы можете получить только, скажем, 10 байтов в первом пакете, и не получить 6 байтов из следующего пакета, пока вы не выполните второй recv
. Таким образом, вы должны продолжать получать, пока не получите все 16 байтов. (Я написал более длинное объяснение в терминах Python , но та же идея применима и к C ++.)
Как только вы это сделаете, все, что нам нужно сделать после получения 16 байтов, это проверить поле длины (которое вы подразумевали, это первые 4 байта в обеих структурах). Если это 16, мы сделали; если нет, мы можем просто продолжать цикл до 64 байтов.
В идеале мы хотим читать в один буфер размером 64 байта вместо чтения 16-байтового буфера и 48-байтового буфера, а затем записывать данные вокруг, чтобы объединить их. Учитывая это, мы можем просто использовать union
, чтобы позволить нам recv
в 64-байтовом массиве символов, но затем получить доступ к первым 16 байтам как reply_type_1
или целому как reply_type_2
.
Итак, вот быстрый и грязный пример (без обработки ошибок, EOF и т. Д.):
typeset union {
reply_type_1 r1;
reply_type_2 r2;
char buf[64];
} msg_type;
int len = 0;
msg_type msg;
while (len < sizeof(reply_type_1)) {
n = recv(sock, &msg.buf[len], sizeof(reply_type_1)-len, 0);
len += n;
}
if msg.r1.length > sizeof(reply_type_1) {
while (len < sizeof(reply_type_2)) {
n = recv(sock, &msg.buf[len], sizeof(reply_type_2)-len, 0);
len += n;
}
do_stuff_r2(msg.r2);
} else {
do_stuff_r1(msg.r1);
}
Сохранение в msg.buf
и последующий доступ к msg.r1
- это то же самое, что просто получить char buf[64]
и затем выполнить do_stuff_r1(*reinterpret_cast<reply_type_1 *>(&buf))
. Таким образом, если do_stuff_r1
принимает reply_type_1
, он получает копию первых 16 байтов в виде структуры reply_type_1
, а если он принимает reply_type_1 &
, он получает ссылку на первые 16 байтов как reply_type_1
struct.