Каков наилучший способ достижения буферизованного чтения из канала в C ++? - PullRequest
0 голосов
/ 30 июня 2018

Я отслеживаю конец чтения канала в цикле 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 *

Спасибо за вашу поддержку!

...