首页 > 解决方案 > 如果 POSIX 套接字“读取”函数返回 0,是否表明发生了错误?

问题描述

我正在使用遗留代码。此代码在套接字上调用“读取”。如果读取函数返回 0 或以下,调用函数将抛出错误。

n = read(sock, &buff[bytesRead], bytesToRead - bytesRead);
if (n <= 0) {
    syslog(LOG_CRIT, "ReadFromSocket: read() failed, errno=%d\n", errno);
    return FALSE;
}

但是,我注意到这个函数在“errno”= 0 时抛出了一个错误。

我很好奇我是否遇到了读取函数返回 0 的边缘情况,这被错误地解释为错误。

返回值 0 是否表示实际错误?

标签: csocketsposix

解决方案


不,返回值为零并不表示错误。read()的文档说:

成功完成后,这些函数应返回一个非负整数,指示实际读取的字节数。否则,函数应返回 -1 并设置 errno 以指示错误。

即:返回值为零仅表示实际读取了零个字节。这不是错误。返回值指示错误-1。仍然为零的事实errno也表明没有发生错误。

至于阻塞/非阻塞部分:

如果fildes [ie: first parameter] 指的是一个套接字,read()应该等同于没有设置标志的recv() 。

那里说:

如果套接字上没有可用的消息并且在套接字的文件描述符上没有设置 O_NONBLOCK,则recv()将阻塞直到消息到达。如果套接字上没有可用的消息并且在套接字的文件描述符上设置了 O_NONBLOCK,recv()将失败并将 errno 设置为 [EAGAIN] 或 [EWOULDBLOCK]。

请记住,该文件是一个套接字,这转换为:

  • 在阻塞模式下,read()/recv()调用将等待,直到有更多可用数据。因此,返回值为零应表明套接字已关闭,将不再接收数据。可以争论这是否是一个错误,但它表明有序关闭,所以我不会将其视为错误,而只是“这里没有更多数据可读取,继续!” 反而。
  • 在非阻塞模式下,read()/recv()调用将返回-1并且errno可以是EAGAINEWOULDBLOCK。如果套接字已正确关闭,则零仍然可以作为非阻塞模式的返回值出现。

概括:

零并不表示错误。如果出现以下情况,则可以返回零:

  • 套接字已按顺序关闭,无法接收更多数据(在阻塞和非阻塞模式下),或者
  • 已收到大小为零的数据报,或
  • 通过第三个参数向read().

推荐阅读