Определение количества байтов, готовых к recv () 'd - PullRequest
1 голос
/ 13 октября 2010

Я могу использовать select (), чтобы определить, будет ли блокироваться вызов recv (), но как только я определил, что это байты, которые нужно прочитать, это способ узнать, сколько байтов в настоящее время доступно, прежде чем я на самом делевызовите recv ()?

Ответы [ 2 ]

4 голосов
/ 15 октября 2010

Если ваша ОС предоставляет его (и большинство это делает), вы можете использовать ioctl (.., FIONREAD, ..):

int get_n_readable_bytes(int fd) {
    int n = -1;
    if (ioctl(fd, FIONREAD, &n) < 0) {
        perror("ioctl failed");
        return -1;
    }
    return n;
}

Windows предоставляет аналогичный ioctlsocket (.., FIONREAD, ..), который ожидает указатель на unsigned long:

unsigned long get_n_readable_bytes(SOCKET sock) {
    unsigned long n = -1;
   if (ioctlsocket(sock, FIONREAD, &n) < 0) {
       /* look in WSAGetLastError() for the error code */
       return 0;
   }
   return n;
}

Вызов ioctl должен работать на сокетах и ​​некоторых других fds, но не на всех fds. Я считаю, что он прекрасно работает с сокетами TCP практически на любой бесплатной Unix-подобной ОС, которую вы, вероятно, будете использовать. Его семантика немного отличается для UDP-сокетов: для них он сообщает вам количество байтов в следующей дейтаграмме.

Вызов ioctlsocket в Windows (очевидно) будет работать только на сокетах.

2 голосов
/ 13 октября 2010

Нет, протокол должен это определить. Например:

  • Если вы используете сообщения фиксированного размера, вы знаете, что вам нужно прочитать X байтов.
  • Вы можете прочитать заголовок сообщения, который указывает X байтов для чтения.
  • Вы можете читать, пока не будет найден конечный символ / последовательность.
...