我正在编写一个客户端-服务器程序。服务器正在 readfd1
上进行 select()
操作,等待读取 readfd1
的就绪状态。如果准备就绪,服务器正在收集数据并打印。有一段时间一切都很好,但过了一段时间后,套接字 recv()
失败,errno
设置为 ETIMEDOUT
。现在我想重写我的程序来阻止这些错误情况。于是我读了理查德·史蒂文斯(Richard Stevens)的《Unix网络编程》,其中规定了select()
解锁的4个条件。以下是引起我注意的 2 个条件
A. client sent FIN, here return value of `recv()` will be `0`
B. some socket error, here return value of `recv()` will be `-1`.
我的问题是,套接字错误是否会关闭连接?如果是这样,那为什么上面两个条件是分开的呢。如果没有,套接字上的下一个 recv()
是否有效?
最佳答案
如果recv()
返回0,则另一端已主动且优雅地关闭了连接。
如果 recv()
返回 -1,则连接(可能)出现错误,并且不再可用。
这意味着您可以区分对等方关闭连接和连接上发生的错误。在这两种情况下,常见的做法是close()
您的套接字端。
还有两点需要考虑:
如果 recv()
返回 -1,您应该检查 errno,因为它可能并不表示真正的错误。
如果您已将套接字置于非阻塞模式,则 errno
可以为 EAGAIN/EWOULDBLOCK
;如果系统调用被以下命令中断,则可能为 EINTR
一个信号。所有其他 errno
值都表示连接已断开,您应该将其关闭。
TCP 可以半双工运行。如果对等方仅关闭了连接的写入端,则 recv()
在您端返回 0。常见的做法是认为连接已完成,并关闭连接的一端,但您可以继续写入,另一端可以继续从中读取。是否仅关闭 TCP 连接的读端或写端由 shutdown()
函数控制。
关于c - 套接字错误是否意味着套接字已关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16814552/