Я отслеживаю конец чтения канала в цикле select
и считываю его с помощью read
, когда доступны данные. Я всегда ожидаю определенный формат данных через канал, который (для примера) имеет тип struct packet_t
. Мой первоначальный код выполнил следующие операции над дескриптором файла после того, как ему позвонил select
:
int
read_packet(int fd)
{
struct packet_t pkt;
int read_bytes = read(fd, &pkt, sizeof(pkt));
if (bytes_read <= 0)
{
/* handle some sort of error */
return -E_SOCK;
}
else if (bytes_read < sizeof(pkt))
{
/* return bad message format */
return -E_BADMSG;
}
/* do something with the packet */
return E_OK;
}
Очевидно, что вышеприведенное не в состоянии сделать то, что я хотел, потому что может случиться так, что read
вызов вернет меньше байтов, чем sizeof(pkt)
только из-за некоторых задержек, и позже, остальные байты будут доставлены как хорошо, заканчивая пакет. Однако мой код предполагает, что если полный пакет не был получен при первом вызове read
, то это должно быть ошибкой передачи, и все последующие пакеты будут отброшены как плохие.
Чтобы это исправить, мне нужно буферизовать чтение, то есть прочитать в отдельный буфер и интерпретировать содержимое буфера как пакет, только если количество принятых байтов не меньше sizeof(pkt)
.
Мои вопросы таковы: существует ли класс или метод c ++, позволяющий добиться правильного буферизованного чтения? Например, я могу создать класс mybuffer
, который содержит уже прочитанные байты, и когда он достигает порогового значения, он вызывает обратный вызов, позволяющий мне прочитать пакет. Однако я не хочу изобретать колесо, если оно есть, и спрашиваю, есть ли решение в стандартной библиотеке (например, с использованием iostream
или в других библиотеках c ++, таких как boost
. *). 1021 *
Спасибо за вашу поддержку!