确定准备接收的字节数

时间:2010-10-13 17:29:51

标签: select blocking libc

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

2 个答案:

答案 0 :(得分: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调用应该适用于套接字和其他一些fds,但不适用于所有fds。我相信它可以在几乎任何你可能使用的免费unix-like操作系统上使用TCP套接字。它的语义与UDP套接字略有不同:对于它们,它告诉你下一个数据报中的字节数。

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

答案 1 :(得分:2)

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

  • 如果您使用固定大小的消息,那么您知道需要读取X字节。
  • 您可以读取一条消息标题,指示要读取的X字节。
  • 您可以阅读,直到找到终端字符/序列。