TCP:recv()正在获取EconReset

TCP:recv()正在获取EconReset,c,sockets,tcp,C,Sockets,Tcp,我正在尝试使用TCP在linux上实现一个简单的客户机/服务器程序 以及标准socket.h库。处理多个客户端的服务器,每个客户端可以随时关闭()或关闭()套接字 在服务器端(使用非阻塞读取): 我让recv()返回-1,并将错误设置为EconReset。如果客户端已关闭连接,则连接不应recv()返回0?如果客户端在未读取已发送数据的情况下关闭其端,则您可能会获得EconReset。如果他正确地关闭了连接,您将得到0 如果远程对等方已完全关闭连接,并且本地端没有更多的字节等待读取,则是,rec

我正在尝试使用TCP在linux上实现一个简单的客户机/服务器程序 以及标准socket.h库。处理多个客户端的服务器,每个客户端可以随时关闭()或关闭()套接字

在服务器端(使用非阻塞读取):


我让recv()返回-1,并将错误设置为EconReset。如果客户端已关闭连接,则连接不应recv()返回0?

如果客户端在未读取已发送数据的情况下关闭其端,则您可能会获得EconReset。如果他正确地关闭了连接,您将得到0

如果远程对等方已完全关闭连接,并且本地端没有更多的字节等待读取,则是,
recv()
应返回
0
。因此,如果您得到一个
ECONNRESET
,那么可以合理地假设有序关闭并不是发生的事情

ECONNRESET
通常表示远程对等方在没有首先完全关闭连接的情况下发送了RST数据包。这可能有很多原因。或者,正如EJP所观察到的,复位也可能起源于本地


在任何情况下,在
econReset
之后,假设您能够从套接字中读取任何内容都是不合理的,因此在您的特定情况下,您可能应该像处理
recv()
返回
0
,+/-日志一样处理它。

原因很多,包括但不限于:

  • 对等方故意重置连接
  • 对等方在仍有未读数据挂起时关闭了连接
  • 您已将数据发送到已被对等方关闭的连接
  • 您有挂起的写入数据,TCP重试已超时
  • TCP keepalive检测到连接丢失
这是一个致命错误,您应该在收到套接字时关闭它

每个客户端都可以
close()
shutdown()
随时打开套接字


不,他不能。请参见上文。

重置可以在您端和对等端进行。您应该将其视为连接上的致命错误来处理,而不是完全断开连接。@EJP,所说的“您”是指OP,用于他描述的特定程序,而不是一般的“您”。我已经澄清了。在这种情况下,您会得到它,但还有其他的。tcpdump会告诉您实际发生了什么我想知道为什么recv中没有提到这个严重的致命错误man@susdu官方X/Open文档中提到了这种错误情况:如果。。。[EconReset]对等方强制关闭了一个连接。@susdu“协议层可能会产生其他错误…”
int nBytes;
if ((nBytes = recv(socket, buffer, BUFFER_SIZE, MSG_DONTWAIT)) == -1)
{
    if (errno != EAGAIN && errno != EWOULDBLOCK)
    {
        //print to log
    }

}
if (nBytes == 0)
{

    //other side closed the connection
}