Если ваша ОС предоставляет его (и большинство это делает), вы можете использовать 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 (очевидно) будет работать только на сокетах.