De ce socket infinit returnează -1 (errno:104) (Programare, C, Prize, Tcp)

niko a intrebat.
a intrebat.

Programul meu socket este o structură server-client.

Ceva ciudat, există o probabilitate scăzută ca atunci când socket-ul TCP tocmai se construiește (clientul se conectează și serverul acceptă).

și folosesc select decât să citesc socket-ul, acesta va returna -1 și errno este 104 (Conexiune resetată de către omolog).

Dar eu nu trimit nimic nici serverului, nici clientului, în mod normal ar trebui să se blocheze la funcția select (funcția mea select nu a stabilit o limită de timp), dar funcția de citire returnează -1.

De ce se întâmplă acest lucru? Sau cum aș putea obține mai multe detalii pentru a depana această problemă?

Vă mulțumesc tuturor.

Platformă: ubuntu 13.04 64bits, compilator gcc

versiunea minimă a codului meu:

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
", 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 (funcția mea de citire):

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

Comentarii

  • Nu avem o minge de cristal. Vă rugăm să postați o versiune minimă a codului dvs. care să demonstreze problema. –  > Por Barmar.
  • îmi pare rău și am postat. mulțumesc.  > Por niko.
1 răspunsuri
user207421

se va returna -1 și errno este 104(Conexiune resetată de către peer)

Deci conexiunea a fost resetată de către peer. Asta se poate întâmpla oricând. Este în afara controlului tău. Acțiunea corectă este să închideți socket-ul și să uitați de el. Conexiunea nu mai există. Încercarea de a selecta și de a citi din nou de pe ea este doar un optimism deplasat.

Comentarii

  • Da, am închis-o, dar nu știu de ce se întâmplă. Nu am trimis nimic. 🙁 –  > Por niko.
  • Dacă l-ai fi închis, nu ai fi selectat din nou pe el și nu ai fi apelat read() din nou, și obținând retururi infinite de -1, așa cum este descris în titlu, deci nu ți-ai mai pune întrebarea. Aveți dreptate în ceea ce privește faptul că nu știți de ce s-a întâmplat. Nu se poate. Doar colegul știe acest lucru. Este doar o realitate a vieții în rețea, iar codul dvs. trebuie să fie suficient de robust pentru a face față acestei situații. –  > Por user207421.
  • Mulțumesc pentru explicații, dar pot să vă întreb: „nu veți selecta din nou și nu veți apela din nou read()”, vă referiți la client, server sau la ambele? Aceasta este o parte a codului, există o altă parte despre serverul acceptă și funcția de conectare a clientului, astfel încât funcția mea de citire nu va citi un fd închis. –  > Por niko.
  • Mă refer la codul pe care l-ați descris în întrebarea dvs. care face o selecție și apoi o citire. Întrebarea dvs. se intitulează „infinite return -1”. Acest lucru se poate întâmpla doar dacă nu închideți socket-ul atunci când primiți eroarea. Este de înțeles. –  > Por user207421.

Tags:, ,