Why socket infinite return -1 (errno:104)

22,589

it will return -1 and errno is 104(Connection reset by peer)

So the connection was reset by the peer. That can happen any time. It's out of your control. The correct action is to close the socket and forget about it. The connection no longer exists. Trying to select and read from it again is just misplaced optimism.

Share:
22,589
niko
Author by

niko

Updated on July 09, 2022

Comments

  • niko
    niko almost 2 years

    My socket program is a server-client structure.

    Something strange, there have a low probability that when the TCP socket just construct(client connect and server accept).

    and I use select than read the socket, it will return -1 and errno is 104(Connection reset by peer).

    But I do not send anything neither server nor client, in a normal way it should block at select function(my select function did not set time-out limit), but the read function return -1.

    Why it happen? Or how can I do can get more detail to debug this problem?

    Thank you all.

    Platform: ubuntu 13.04 64bits, gcc compiler

    minimal version of my code:

    server:

    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 );
            }
        }
    

    client (my read function):

    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;
    }
    
  • niko
    niko over 10 years
    yes I close it, but i don't know why it happen. I didn't send anything. :(
  • user207421
    user207421 over 10 years
    If you had closed it, you wouldn't be re-selecting on it, and calling read() again, and getting the infinite returns of -1 as described in your title, so you wouldn't be asking the question. You are correct in that you don't know why it happened. You can't. Only the peer knows that. It's just a fact of life in networking, and your code has to be robust enough to cope with it.
  • niko
    niko over 10 years
    Thank for your explain, may I ask your " you wouldn't be re-selecting on it, and calling read() again" is means client or server or both? This is a part of code, there have another part about server accept and client connect function, so my read function will not read a closed fd.
  • user207421
    user207421 over 10 years
    I'm talking about the code you described in your question that does a select and then a read. Your question is entitled 'infinite return -1'. That can only happen if you don't close the socket when you get the error. It stands to reason.