[C] Socket hängt fest bei recv()

fish-guts

Erfahrenes Mitglied
Guten Tag Allerseits

Ich habe einen kleinen Server, der auf Befehle von aussen wartet und diese dann ausführen soll.

Ich öffne den Socket, verbinde mit dem Sever und die Verbindung steht.

Nun kommt es manchmal vor, dass bei recv() einfach nichts mehr passiert. Weder ein gültiger noch ein ungültiger Wert wird zurückgeliefert.

So sieht der Code aus:

Code:
static void rn_start(void)
{
    int s,u;
    char buf[IRCBUF_SIZE];
    memset(&buf,0,sizeof(buf));
#ifndef _WIN32
    if(signal(SIGALRM, timer_event_handler)==SIG_ERR)
    {
        addlog(2,"Error in signal()\n");
        return;
    }
    set_timer(2);
#endif
    create_files();
    /* initialisiert den socket und verbindet mit dem server */
    mainsock = sock_init();
    if(mainsock<0)
    {
        rn_cput("Error initializing socket. Please restart services\n");
        exit(EXIT_FAILURE);
    }
    addlog(1,"Services successfully started");
    mainsock = sock_connect();
    if(mainsock<0) {
        printf("FATAL ERROR\n");
        exit(EXIT_FAILURE);
    }
    /* hauptschleife wo er auf befehle wartet - bis hier funktioniert alles einwandfrei */
    for(;;)
    {
/* hier passiert der fehler - er hängt einfach, ohne irgendwas zu machen */
        s = recv(mainsock,buf,IRCBUF_SIZE,MSG_PEEK);
        printf("%s\n",buf);
        printf("s: %i\n",s);
        if(s>0)
        {
            u = recv(mainsock,buf,sizeof(buf),0);
            char *pch = strtok(buf,"\r\n");
            while(pch!=NULL)
            {
                strcpy(ircbuf,pch);
                parse();
                ircbuf[s]=0;
                pch = strtok(NULL,"\r\n");
            }
        }
/* wird gar nie ausgeführt, weil das programm eben hängt */
        else {
            printf("Connection to Server lost. Please restart services\n");
            exit(EXIT_FAILURE);
        }
    }
}
Nun ist es so, dass es manchmal tadellos funktioniert, aber manchmal eben leider nicht. Wenn mir jemand einen Tipp geben könnte, wäre ich sehr froh.


Vielen Dank schon im Voraus.


Liebe Grüsse

FG
 
Hallo,

Sockets sind standardmäßig blockierend. Wenn keine Daten gesendet wurden, aber trotzdem recv() aufgerufen wird, dann wartet die Funktion solange, bis wieder was gesendet wird. Um die Blockade zu vermeiden, kann man z.B. mit select() überprüfen, ob sich bei dem betreffenden Socket was tut.

Gruß
MCoder
 
Blocking sockets löst man z.B. so:

Code:
bool readable(SOCKET socket)
{
    FD_SET fdSet;
    TIMEVAL timeout;
    timeout.tv_sec = 0;
    timeout.tv_usec = 0;
    long status;

    FD_ZERO(&fdSet);
    FD_SET(socket,&fdSet);
    status = select(0,&fdSet,0,0,&timeout);
    if(status <= 0)
      {
          FD_ZERO(&fdSet);
      }
    if(!FD_ISSET(socket,&fdSet))
      {
          return false;
      }
    return true;
}

static void rn_start(void)
{

.........

if(readable(mainsock))
{
s = recv(...);
}
else
{
printf("Keine Daten empfangen\n");
}

.........

}

Das Dumme daran ist aber, dass dann die Schleife 100% CPU Auslastung verursacht, weil eben nichts mehr blockt oder wartet.
Zur Not kann man einen
Sleep(100);
einbauen, aber so toll ist das auch nicht.
 
Das er in der recv-Funktion 'hängt' ist ganz normal. Er wartet solange in der Schleife bis Daten vom Client kommen. Sobald er Daten empfängt wird er auch weiter machen.
In wie fern hast du gemeint dass dein Programm manchmal funktioniert und manchmal nicht?
 
Moin

select() war die Lösung. habe nun mit select() sichergestellt, dass auch wirklich Daten fliessen und momentan scheints gut zu funktionieren.

Danke für Die inputs.


Gruss

FG
 
Zurück