Avatar billede stringbuffer Nybegynder
01. december 2001 - 12:24 Der er 2 kommentarer og
1 løsning

Non-blocking connect i Linux

Jeg har følgende funktion til at connecte en socket uden at blokere som almindelige connect:

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

Problemet er at den blokerer alligevel.
Hvor har jeg lavet en fejl?
Avatar billede baz Nybegynder
05. december 2001 - 00:13 #1
Hmmm, jeg har noget kode, der ser stort set ligesådan ud, og som virker med asynkron connect. Den eneste forskel er, at jeg bruger fcntl til at sætte O_NONBLOCK flaget istedet for som du at sætte FIONBIO med ioctl. Det burde give samme resultat, men du kan eventuelt lige prøve at bruge en stump kode i stil med:

/* Set nonblocking I/O */
int flags = fcntl(fd, F_GETFL);
fcntl(fd, F_SETFL, O_NONBLOCK);

/* Do connect stuff */

/* Reset to blocking I/O */
fcntl(fd, F_SETFL, flags);

Det virker ihvertfald for mig...
Avatar billede stringbuffer Nybegynder
05. december 2001 - 11:51 #2
Det giver præcist samme resultat som før, altså at den hænger når den host, jeg connecter til, er tavs. Jeg har fundet ud af at den når hen til select() hvor den stener uendeligt :(((

Det er altså ikke det at sætte en socket til non-blocking, der mislykkes, det virker fint på begge måder.
Avatar billede stringbuffer Nybegynder
05. december 2001 - 17:14 #3
Det virker som om ingen kan finde ud af det. Jeg stiller et spørgsmål vedrørende select() istedet.
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