Verbindung erfolgreich obwohl keiner Server offen



  • Wenn ich folgende Funktion zum verbinden benutze, funktioniert es, allerdings funktioniert es auch wenn ich keinen Server aufmache.

    void Client(int Socket) {
        fcntl(Socket, F_SETFL, O_NONBLOCK);
        sockaddr_in s;
        s.sin_family = AF_INET;
        s.sin_addr.s_addr = inet_addr("127.0.0.1");
        s.sin_port = htons(2269);
        if (connect(Socket, reinterpret_cast<sockaddr*>(&s), sizeof(s)) != 0) {
            if(errno != EINPROGRESS) {
                cout << strerror(errno) << endl;
                return;
            }
        }
        fd_set MySet, ErrorSet;
        timeval MyTimeval;
        cout << "Connecting" << flush;
        while(true) {
            MyTimeval.tv_usec = 0;
            MyTimeval.tv_sec = 0;
            FD_ZERO(&MySet);
            FD_SET(Socket, &MySet);
            FD_ZERO(&ErrorSet);
            FD_SET(Socket, &ErrorSet);
            if(select(Socket + 1, NULL, &MySet, &ErrorSet, &MyTimeval) == -1) {
                cout << strerror(errno) << endl;
            }
            if(FD_ISSET(Socket, &ErrorSet)) {
                cout << "No Server Found!" << endl;
            }
            if(FD_ISSET(Socket, &MySet)) {
                cout << "OK" << endl;
                break;
            }
            cout << "." << flush;
            sleep(1);
        }
    }
    

    Ausgabe

    ConnectingOK
    

    Wie lässt sich herrausfinden ob wirklich eine Verbindung aufgebaut wurde?

    mfg.



  • Vielleicht liegt es an dem an der Option O_NONBLOCK.
    Hier mein C-Quelltext, mit dem es funktioniert:

    sock_fd = socket(PF_INET, SOCK_STREAM, 0);
      if (sock_fd == -1)
       {
        perror("connect: Can't create new socket");
        return(1);
       }
    
      server_addr.sin_family = AF_INET;
      server_addr.sin_port = htons(port);
      err = inet_aton(argv[1], &(server_addr.sin_addr));
      if (err == 0)
       {
        fprintf(stderr, "connect: Bad IP-Address '%s'\n", argv[1]);
        return(1);
       }
    
      err = connect(sock_fd, &server_addr, sizeof(struct sockaddr_in));
      if (err == -1)
       {
        perror("connect: connect() failed");
        return(1);
       }
    


  • Martin G schrieb:

    Vielleicht liegt es an dem an der Option O_NONBLOCK.
    Hier mein C-Quelltext, mit dem es funktioniert:

    sock_fd = socket(PF_INET, SOCK_STREAM, 0);
      if (sock_fd == -1)
       {
        perror("connect: Can't create new socket");
        return(1);
       }
    
      server_addr.sin_family = AF_INET;
      server_addr.sin_port = htons(port);
      err = inet_aton(argv[1], &(server_addr.sin_addr));
      if (err == 0)
       {
        fprintf(stderr, "connect: Bad IP-Address '%s'\n", argv[1]);
        return(1);
       }
    
      err = connect(sock_fd, &server_addr, sizeof(struct sockaddr_in));
      if (err == -1)
       {
        perror("connect: connect() failed");
        return(1);
       }
    

    Leider blockt, dass dann auch und ich wollte es ohne blocken programmieren. Gibt's da auch eine Möglichkeit?

    mfg.



  • Was genau willst du denn mit dem O_NONBLOCK bezwecken?
    Auf der einen Seite sorgst du dafür, dass connect() keinen Fehler bei nicht-Zustandekommen der Verbindung liefert, auf der anderen Seite willst du aber genau eine solche Fehlermeldung erhalten!?



  • Versuch doch mal drauf zu schreiben, dann sollte ein Fehler kommen.



  • Martin G schrieb:

    Was genau willst du denn mit dem O_NONBLOCK bezwecken?
    Auf der einen Seite sorgst du dafür, dass connect() keinen Fehler bei nicht-Zustandekommen der Verbindung liefert, auf der anderen Seite willst du aber genau eine solche Fehlermeldung erhalten!?

    Wenn ich das nonblock wegnehme, blockt es ja, und das will ich vermeiden.

    @kingruedi
    Ich werd's mal ausprobieren, aber geht das nicht eleganter?

    Auch glaub ich dass da sowieso noch der wurm drinn ist, weil was ist, wenn er ne weile braucht fürs connecten? Dann müsst ich ja irgentwie warten bis ich drauf schreibe, sonst denkt er es konnte keine Verbindung hergestellt werden. Versteht ihr was ich meine?

    mfg.



  • joomoo schrieb:

    Wenn ich das nonblock wegnehme, blockt es ja, und das will ich vermeiden.

    Was meinst du mit "blockt es ja"???
    Wenn du einen connect() auf einen nicht geöffneten Port versuchst, kehrt connect() mit einem entsprechenden Fehler zurück - und genau das wolltest du doch bezwecken, oder?

    Ich nutze O_NONBLOCK eigentlich nur in Verbindung mit Devices wie das CD-ROM-Laufwerk. Damit lässt sich das Device ansprechen, auch wenn keine CD eingelegt ist.



  • Martin G schrieb:

    joomoo schrieb:

    Wenn ich das nonblock wegnehme, blockt es ja, und das will ich vermeiden.

    Was meinst du mit "blockt es ja"???
    Wenn du einen connect() auf einen nicht geöffneten Port versuchst, kehrt connect() mit einem entsprechenden Fehler zurück - und genau das wolltest du doch bezwecken, oder?

    Die Funktion kehrt nicht sofort zurück, sie "blockt" das Programm, bis sie eine Verbindung aufgebaut hat, bzw. bis sie es nicht geschafft hat.

    mfg.



  • Das Programm kann dir vor select ja nicht sagen, ob die Verbindung geklappt hat, da du connect ja bewußt nonblocking verlaufen lässt. Daher erfährst du das erst, wenn du eine Operation auf dem Socket ausführen willst. exceptfds wird bei select für OOB Daten benutzt und nicht um EOF oder Fehler zu signalisieren. Siehe man: select_tut (hoffe mal, dass die manpage auf dem Server auch existiert 🙂 wenn nicht hier ist die entscheidende Stelle:

    select_tut(2) schrieb:

    exceptfds
    This set is watched for exceptions or errors on any of the file
    descriptors. However, that is actually just a rumor. How you use
    exceptfds is to watch for out-of-band (OOB) data. OOB data is
    data sent on a socket using the MSG_OOB flag, and hence
    exceptfds only really applies to sockets. See recv(2) and
    send(2) about this. After select() has returned, exceptfds will
    be cleared of all file descriptors except for those descriptors
    that are available for reading OOB data. You can only ever read
    one byte of OOB data though (which is done with recv()), and
    writing OOB data (done with send()) can be done at any time and
    will not block. Hence there is no need for a fourth set to check
    if a socket is available for writing OOB data.

    Daher bleibt dir nichts übrig, als ein write auszuführen und den Fehler zu überprüfen.


Anmelden zum Antworten