1

我可以使用 select() 来确定对 recv() 的调用是否会阻塞,但是一旦我确定它们是要读取的字节,它们就是一种在我实际调用 recv() 之前查询当前可用字节数的方法)?

4

2 回答 2

4

如果您的操作系统提供它(并且大多数都提供),您可以使用 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 调用应该适用于套接字和其他一些 fd,但并非适用于所有 fd。我相信它几乎可以在您可能使用的任何免费的类 unix 操作系统上与 TCP 套接字一起工作。对于 UDP 套接字,它的语义略有不同:对于它们,它告诉您下一个数据报中的字节数。

Windows 上的 ioctlsocket 调用将(显然)仅适用于套接字。

于 2010-10-15T06:06:52.590 回答
2

不,协议需要确定这一点。例如:

  • 如果您使用固定大小的消息,那么您知道您需要读取 X 个字节。
  • 您可以读取指示要读取 X 个字节的消息头。
  • 您可以阅读直到找到终端字符/序列。
于 2010-10-13T17:33:08.593 回答