首页 文章

TCP:recv()获取ECONNRESET

提问于
浏览
2

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

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

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
}

我得到recv()返回-1并将错误设置为ECONNRESET . 如果客户端已关闭,连接不应该recv()返回0?

3 回答

  • 7

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

    • 对等方故意重置连接

    • 对等方关闭了连接,而他仍然有待处理的未读数据

    • 您已将数据发送到已由对等方关闭的连接

    • 您有待处理的写入数据,并且TCP重试已超时

    • TCP keepalive检测到连接丢失 .

    这是致命错误,您应该在获得它时关闭套接字 .

    每个客户端可以随时关闭()或关闭()套接字 .

    不,他不能 . 往上看 .

  • 4

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

    ECONNRESET 经常表示远程对等方发送了RST数据包而没有先干净地关闭连接 . 造成这种情况的原因有很多 . 或者,正如EJP观察到的那样,重置也可能在本地产生 .

    在任何情况下,在 ECONNRESET 之后,假设您将能够从套接字中进一步读取任何内容是不合理的,因此在您的特定情况下,您可能应该像处理 recv() 返回 0 ,/ - 记录一样处理它 .

  • 3

    如果客户端在没有读取发送数据的情况下关闭他的一方,您可能会获得ECONNRESET如果他正确地关闭连接你就会得到0 .

相关问题