【问题标题】:Why does reading a non-blocking socket return an error status code为什么读取非阻塞套接字会返回错误状态码
【发布时间】:2019-07-04 00:51:31
【问题描述】:

成功读取设置为非阻塞的套接字后,该套接字暂时不可用。第一次调用read 时已接收到所有数据,但错误返回值会持续约 5 秒。之后read 返回 0 并且套接字再次可用。

为什么套接字首先返回错误?

设置非阻塞套接字:

/* Non blocking */
int flags = fcntl(sockfd, F_GETFL, 0);
fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);

读取套接字并打印:

result = read(sockfd, response + bytes_read, RESPONSE_SIZE - bytes_read);
printf("%d | %d | %s\n", (int)result, errno, strerror(errno));
printf("%d | %d | %d | %d | %d | %d | %d | %d \n",
            EAGAIN, EWOULDBLOCK, EBADF, EFAULT, EINTR, EINVAL, EIO, EISDIR);

结果:

152 | 115 | Operation now in progress
11 | 11 | 9 | 14 | 4 | 22 | 5 | 21 

-1 | 11 | Resource temporarily unavailable
11 | 11 | 9 | 14 | 4 | 22 | 5 | 21 

【问题讨论】:

  • 即使它是非阻塞的,无法获取数据也是一个错误,这就是为什么您在errno 中得到EWOULDBLOCK 并返回-1

标签: c file-descriptor


【解决方案1】:

当套接字设置为非阻塞时,如果没有可读取的内容,read 函数将返回 -1 并将 errno 设置为 EAGAINEWOULDBLOCK。这样你就知道没有什么可读的了,此时你可以在重试之前做其他事情。

如果read 返回 0,这意味着文件结束被命中,或者套接字发生了关闭。

【讨论】:

    【解决方案2】:

    如果 FIFO 或套接字类型的非阻塞文件中没有可用数据,读取将失败并返回 -1 并将 errno 设置为 EWOULDBLOCK。这个errno 代码的别名是EAGAIN,它表示您再试一次(稍后,在输入更多数据后)。

    来自套接字上的read0 返回值表明意味着文件结束条件(对于套接字而言,这意味着发生了关闭)。

    从读取(2):

    (零表示文件结束)

    ...

    出错时返回-1,并正确设置errno。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-08-19
      • 2011-12-27
      • 2012-07-24
      • 1970-01-01
      • 1970-01-01
      • 2011-10-07
      • 1970-01-01
      相关资源
      最近更新 更多