【问题标题】:Why socket infinite return -1 (errno:104)为什么套接字无限返回 -1 (errno:104)
【发布时间】:2014-02-04 17:48:34
【问题描述】:

我的套接字程序是一个服务器-客户端结构。

奇怪的是,TCP socket刚刚构建时(客户端连接和服务器接受)的概率很低。

我使用 select 而不是读取套接字,它将返回 -1 并且 errno 为 104(对等连接重置)。

但我既不发送服务器也不发送任何客户端,正常情况下它应该在选择函数处阻塞(我的选择函数没有设置超时限制),但读取函数返回-1。

为什么会这样?或者我该怎么做才能获得更多细节来调试这个问题?

谢谢大家。

平台:ubuntu 13.04 64bits,gcc编译器

我的代码的最小版本:

服务器:

for(;;)
    {
        rset= allset;
        select(maxfd+1, &rset, NULL, NULL, NULL);

        //read socket
        if( FD_ISSET(fconn[i].fd, &rset) )
        {
            len=read(fconn[i].fd, &tcp_buf.b[4], PACKET_LENGTH);

            //the connection will close
            if( len<0 )
            {
                printf("%s, fconn %s read length:%d, errno:%d(%s), close connection\n", crtTime(), fconn[i].ip, len, errno, strerror(errno) );
                close( fconn[i].fd );
                FD_CLR( fconn[i].fd, &allset );
            }
        }

        //construct new connection
        if( FD_ISSET(forwardSockfd, &rset) )
        {
            clilen= sizeof(cliaddr);
            connfd= accept( forwardSockfd, (struct sockaddr*)&cliaddr, &clilen );
            inet_ntop( AF_INET, &cliaddr.sin_addr, ip, sizeof(ip) );
            client_port= (int)cliaddr.sin_port;

            //set send buffer size
            int sendBuf= SOCKET_BUF_LENGTH;
            setsockopt(connfd, SOL_SOCKET, SO_SNDBUF, &sendBuf, sizeof(sendBuf));

            FD_SET( connfd, &allset );
        }
    }

客户端(我的读取功能):

int readline(int fd, void* ptr, int len)
{
    int    rtn= len;
    void*  bp= ptr;
    int    rc;
    fd_set fdset;

    FD_ZERO(&fdset);
    FD_SET(fd, &fdset);
    while( len>0 )
    {
        select(fd+1, &fdset, NULL, NULL, NULL);
        rc=read(fd, bp, len);


        if(rc>0)
        {
            bp+= rc;
            len-= rc;
        }

        else
        {
            return rc;
        }
    }

    return rtn;
}

【问题讨论】:

  • 我们没有水晶球。请发布演示问题的代码的最小版本。
  • 抱歉并已发布。谢谢

标签: c sockets tcp


【解决方案1】:

它会返回 -1 并且 errno 是 104(连接被对端重置)

所以连接被对等方重置。这可能随时发生。这是你无法控制的。正确的做法是关闭套接字并忘记它。连接不再存在。尝试再次选择并从中读取只是一种错误的乐观。

【讨论】:

  • 是的,我关闭了它,但我不知道为什么会这样。我什么都没寄。 :(
  • 如果你关闭了它,你就不会重新选择它,并再次调用read(),并得到标题中描述的 -1 的无限回报,所以你不会'不是在问这个问题。你是对的,因为你不知道为什么会发生。你不能。只有同行知道。这只是网络生活中的一个事实,您的代码必须足够健壮以应对它。
  • 感谢您的解释,请问您的“您不会重新选择它,并且再次调用 read()”是指客户端或服务器还是两者兼而有之?这是一部分代码,还有一部分是关于服务器接受和客户端连接功能,所以我的读取功能不会读取关闭的fd。
  • 我说的是您在问题中描述的代码,它执行选择然后读取。您的问题的标题是“无限回报-1”。仅当您在收到错误时不关闭套接字时才会发生这种情况。这是有道理的。
猜你喜欢
  • 1970-01-01
  • 2015-06-06
  • 2010-10-09
  • 1970-01-01
  • 1970-01-01
  • 2019-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多