Avatar billede stringbuffer Nybegynder
05. december 2001 - 17:21 Der er 4 kommentarer og
1 løsning

problem med select()

Jeg har en funktion, der skal connecte en socket med et timeout på etableringen af forbindelsen. Jeg bruger ioctl med FIONBIO (eller fcntl med O_NONBLOCK)
til at sætte min socket til non-blocking, hvorefter jeg kalder connect(), sætter socket til blocking-mode igen og venter med select(). Jeg har sat timeout på select til 3 sekunder, men det virker tilsyneladende kun hvis den vært, jeg prøver at connecte til, er i live. Ellers hænger select uendeligt.

Hvad skal jeg gøre for at få select() til at returnere med timeout når værten er kaput?

Jeg kører under RedHat Linux med 2.4.5 kerne. Koden til min funktion er som følger:

int do_connect(int fd, struct sockaddr *remote, socklen_t len, int *err)
{
    struct timeval timeout;
    int saveflags,ret,back_err;
    fd_set fd_w;

    int on = 1, off = 0;

    timeout.tv_sec = 3;
    timeout.tv_usec = 0;
if (ioctl(fd, FIONBIO, &on) < 0)
    {
        perror(\"ioctl1\\n\");
        *err = errno;
        return -1;
    }

    /* This will return immediately */
    *err=connect(fd,remote,len);
    back_err=errno;

if (ioctl(fd, FIONBIO, &off) < 0)
    {
        perror(\"ioctl2\\n\");
        *err = errno;
        return -1;
    }

    /* return unless the connection was successful or the connect is still in progress. */
    if(*err<0 && back_err!=EINPROGRESS)
    {
        perror(\"connect\\n\");
        *err=errno;
        return -1;
    }

    FD_ZERO(&fd_w);
    FD_SET(fd,&fd_w);

    *err=select(fd+1, NULL, &fd_w,NULL, &timeout);

    if(*err<0)
    {
        perror(\"select\\n\");
        *err=errno;
        return -1;
    }

    /* 0 means it timeout out & no fds changed */
    if(*err==0)
    {
        close(fd);
        *err=ETIMEDOUT;
        return -1;
    }

    /* Get the return code from the connect */
    len=sizeof(ret);
    *err=getsockopt(fd,SOL_SOCKET,SO_ERROR,&ret,&len);
    if(*err<0)
    {
        perror(\"getsockopt\\n\");
        *err=errno;
        return -1;
    }

    /* ret=0 means success, otherwise it contains the errno */
    if(ret)
    {
        *err=ret;
        return -1;
    }
    *err=0;
    return 0;
}
Avatar billede jpk Nybegynder
06. december 2001 - 08:39 #1
Hvad med at lave din connect i en separat tråd, så kan du nedlægge tråden fra din hovedtråd hvis du ikke får svar inden for en bestemt tidsperiode.

Avatar billede stringbuffer Nybegynder
19. december 2001 - 11:37 #2
Hvordan vil du vente et bestemt stykke tid på at tråden har udført arbejdet? pthread_join venter jo uendeligt. Har du noget kode, der kan starte en trådfunktion og dræbe den hvis den ikke exiter indenfor et bestemt stykke tid?

Det er godt nok ikke det, spørgsmålet blev stillet i, men jeg skal nok give lidt point for det oz.
Avatar billede jpk Nybegynder
19. december 2001 - 12:15 #3
Jeg har ikke noget kode der lige gør det jeg beskrev ovenfor. Det jeg havde tænkt mig er som følger:

Fra din main thread, start en ny tråd der skal gøre det nødvendige arbejde.
I din main thread, vent et stykke tid (alt efter hvad der nu er passende).
Check om arbejdet er udført (tråden kan fx give besked herom); Hvis arbejdet ikke er udført inden for den fastsatte tid, dræb tråden!

Avatar billede stringbuffer Nybegynder
30. marts 2002 - 14:23 #4
Det dur ikke, for det ville medføre at der skal ventes også selvom arbejdet blev udført øjeblikkeligt. Det kan man ikke have i den applikation, jeg skal lave.
Avatar billede stringbuffer Nybegynder
22. maj 2002 - 13:22 #5
Nå, det kan åbenbart ikke lade sig gøre. Måske har Linux en broken TCP/IP stack, hvem ved...
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester

IT-JOB

Forsvarsministeriets Materiel- og Indkøbsstyrelse

Cyberdivisionen søger IT-supporter til Lokal IT Servicecenter i Karup

Capgemini Danmark A/S

IGNITE Graduate Program 2026

Forsvarsministeriets Materiel- og Indkøbsstyrelse

Lead DevSecOps