我正在处理遗留代码。此代码在套接字上调用“读取”。如果读取函数返回 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 是否表示实际错误?
最佳答案
不,返回值为零并不表示错误。 documentation for read()说:
Upon successful completion, these functions shall return a non-negative integer indicating the number of bytes actually read. Otherwise, the functions shall return -1 and set errno to indicate the error.
即:返回值为零仅表示已实际读取零字节。这不是错误。错误由返回值 -1
指示。 errno
仍然为零的事实也表明没有发生错误。
至于阻塞/非阻塞部分:
If fildes [i.e.: first parameter] refers to a socket, read() shall be equivalent to recv() with no flags set.
上面写着:
If no messages are available at the socket and O_NONBLOCK is not set on the socket's file descriptor, recv() shall block until a message arrives. If no messages are available at the socket and O_NONBLOCK is set on the socket's file descriptor, recv() shall fail and set errno to [EAGAIN] or [EWOULDBLOCK].
记住文件是一个套接字,这转化为:
- 在阻塞模式下,
read()
/recv()
调用将等待直到有更多数据可用。因此,返回值为零应该表示套接字已关闭并且不会再接收到更多数据。人们可以争论这是否是一个错误,但它表示有序关闭,所以我不会将其视为错误,而只是 “这里没有更多数据可读,继续!”。 - 在非阻塞模式下,
read()
/recv()
调用将返回-1
和errno
可以是EAGAIN
或EWOULDBLOCK
。如果套接字已正确关闭,零仍然可以作为非阻塞模式的返回值出现。
总结:
零不表示错误。可以返回零,如果:
- 套接字已有序关闭且无法接收更多数据(无论是阻塞模式还是非阻塞模式),或者
- 已收到大小为零的数据报,或者
- 已通过
read()
的第三个参数请求了恰好为零的字节。
关于c - 如果 POSIX 套接字 "read"函数返回 0,是否表示发生了错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66567823/