listen(...) gibt (null) zurück



  • Hallo zusammen,

    Ich programmiere gerade an einer Server-Client-Applikation in C und auf Linux. Serverseitig verwende ich um nach eingehenden Verbindungen zu horchen die Funktion:

    int listen(int sockfd, int backlog);
    

    Laut man-Pages hat diese zwei mögliche Rückgabewerte (0 oder 1):

    On success, zero is returned. On error, -1 is returned, and errno is set appropriately.

    Da Irgendwas nicht richtig funktionieren wollte hab ich mal folgendes versucht...

    printf("%s\n", listen(*sockfd, 5));
    

    ... und merkwürdigerweise erscheint dann auf der Konsole:

    (null)

    Wie hat das den zu bedeuten? Ist ja nach manpage garnicht möglich! 😕

    Schonmals im Voraus vielen Dank für Antworten!
    claudio



  • Versuchs mal mit %d anstatt %s



  • Versuchs mal mit %d anstatt %s

    Oh, ja... ich muss mich wohl noch an die Narrenfreiheit gewöhnen, die C bietet 😉

    Mein Problem ist damit aber noch nicht gelöst. Ich hab damit erst den Code debuggt, den ich zum Debuggen des eigentlichen Bugs eingefügt hatte 😃
    Zum eigentlichen Bug:

    Ich hab folgende Funktion geschrieben, die auf eingehende Verbindungsanfragen wartet. Sie sollte genau wie listen() 0 oder 1 zurückgeben:

    /*
    Listen for connection
    @ int *sockfd: pointer to socket file descriptor
    */
    listconn(int *sockfd){
      printf("%d\n", listen(*sockfd, 5)); // debugcode
      if(listen(*sockfd, 5) != 0){
        return -1;
      }
      return 0;
    }
    

    Im Mainprogramm ruf ich die listconn() dann folgendermassen auf:

    // listen to connection
      while(listconn(&sockfd) != 0){}
      printf("%s\n", " OK in function listconn()");
      if(listconn(&sockfd) != 0){
        printf("%s\n", " Error in function listconn()");
      }
      else{
        printf("%s\n", " OK in function listconn()");
      }
    

    Zu meiner Verwirrung wird auf die Konsole ausgegeben:

    ...
    0
    OK in function listconn()

    Das heisst, listen() und damit auch listconn() geben sofort nach deren Aufruf 0 zurück, was heisst, dass eine Verbindungsanfrage eingegangen ist. Das wiederum ist nicht möglich, da ich den Clienten, der dies tun könnte, noch nicht einmal gestartet hab.



  • Das heißt NICHT, daß eine Verbindungsanfrage eingegangen ist!

    Zumindest unter Windows heißt es:

    To accept connections, a socket is first created with socket, a backlog for incoming connections is specified with listen, and then the connections are accepted with accept.

    Ich denke, daß es auch unter LINUX eines accept (oder ähnliches) bedarf, um eingehende Verbindungen anzunehmen.



  • Ach, so.. demzufolge bewirkt listen() nur, das der Socket auf listening gesetzt wird und die Aufgabe auf Verbingungen zu warten und diese dann zu akzeptieren. In die While-Schleife eingebunden werden muss also nicht listen() (bzw. listconn()), sondern accept() (bzw. meine eigene Funktion acccon()).

    Doch auch das bleibt schon beim ersten Schleifendurchlauf hängen: 😕

    //accept connection
      while(acccon(&sockfd, &keysockfd, &clientdata) != 0){}
    
    /*
    Accept connection
    @ int *sockfd: pointer to socket file descriptor for listening
    @ int *keysockfd: pointer to socket file descriptor for new connection
    @ struct sockaddr_in *clientdata: Datastructure for saving detail about client
    */
    int acccon(int *sockfd, int *keysockfd, struct sockaddr_in *clientdata){
      printf("%s\n", "1");
      socklen_t sin_size = sizeof(struct sockaddr_in);
      printf("%s\n", "2");
      struct sockaddr_in tempcd = *clientdata; // optimieren: nicht umweg ueber tempcd !!! wie?
      printf("%s\n", "3");
      *keysockfd = accept(*sockfd, (struct sockaddr *) &clientdata, &sin_size);
      printf("%s\n", "4");
      if(*keysockfd == -1){
        printf("%s\n", "5.1");
        return -1;
      }
      printf("%s\n", "5.2");
      return 0;
    }
    

    Denn auf die Konsole wird ausgegeben:

    OK in function getsocket()
    OK in function bindport()
    OK in function listconn()
    1
    2
    3



  • Ohhhh, mein letzter Post beinhaltete Code aus dem Server. Es ist mir beim Verfassen entgangen, dass der Fehler auch noch beim Clienten liegen könnte. Die Ausgabe des folgenden Codes aus dem Clienten scheint dies zu bestätigen:

    // open connection 
      if(newconnection(&sockfd) != 0){
        printf("%s\n", " Error in function newconnection()");    
      }
      else{
        printf("%s\n", " OK in function newconnection()");  
      }
    
    /*
    Open connection to server
    @ int *sockfd: pointer to socket file descriptor
    */
    int newconnection(int *sockfd, int *port, int *ipaddr){ // todo: infos von pointer holen, nicht von define !!!
      printf("%s\n", "1");
      // Adressinformation for ip-connection
      struct sockaddr_in serv_addr;
      printf("%s\n", "2");
      serv_addr.sin_family = AF_INET;
      printf("%s\n", "3");
      serv_addr.sin_port = htons(PORT);
      printf("%s\n", "4");
      serv_addr.sin_family = inet_addr(IPADR);
      printf("%s\n", "5");
      memset(&serv_addr.sin_zero, 0, sizeof(serv_addr.sin_zero));
      printf("%s\n", "6");
      // Try to connect
      if(connect(*sockfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) < 0){
        printf("%s\n", "7.1");
      return -1;
      }
      printf("%s\n", "7.2");
      return 0;
    }
    

    Nun die Konsolenausgabe:

    OK in function getsocket()
    1
    2
    3
    4
    5
    6
    7.1
    Error in function newconnection()

    Daraus geht hervor, dass der Fehler irgendwo in Zeile 19 des zweiten Code-Stücks liegen muss. Gerade, da das Kompilieren einwandfrei funktioniert und beim Ausführen nur -1 von connect() zurückgegeben wird finde ich die falsche Stelle nicht.


Anmelden zum Antworten