Standard C Socket funktion close killt QT3



  • Sorry, war an der UNI und hatte den Quellcode nicht dabei.
    Also hier der Code von qt3:

    class MyChat : public QWidget
    {
      Q_OBJECT;
      public:
        MyChat(void);
    
      public slots:
        void post(void);
    
      private:
        QTextEdit* display;
        QLineEdit* edit_msg;
        QPushButton* send_btn;
        QListBox*    user_list;
    }; 
    
    MyChat::MyChat(void)
    {
      setMinimumSize(600, 500);
      setMaximumSize(600, 500);
    
      display = new QTextEdit(this);
      display->setGeometry(5,5,400,450);
      display->setReadOnly(true);
    
      edit_msg = new QLineEdit(this);
      edit_msg->setGeometry(5, 460, 400, 30);
    
      send_btn = new QPushButton("SEND", this);
      send_btn->setGeometry(410, 460, 180, 30);
      QObject::connect(send_btn, SIGNAL(clicked()), this , SLOT(post()));
    
      user_list = new QListBox(this);
      user_list->setGeometry(410, 5, 180, 450);
      user_list->insertItem("HANS");
      user_list->insertItem("JUERGEN");
    }
    

    Das Problem tritt effektiv im Slot auf wenn ich eine Funktion, die ich bereits im Vorhinein geschrieben habe, aufrufe:

    void MyChat::post() {
      int socket = connect_to("127.0.0.1", 7777);
      // handle socket
      close(socket);
    }
    

    Die connect_to Funktion sieht folgendermaßen aus:

    int connect_to(char* host_adress, int host_port) {
      struct sockaddr_in 	 serverAddress;
      struct hostent 	*hostInfo;
    
      hostInfo = gethostbyname(host_adress);
    
      serverAddress.sin_port = htons(host_port);
      serverAddress.sin_family = hostInfo->h_addrtype;
      memcpy((char *) &serverAddress.sin_addr.s_addr, hostInfo->h_addr_list[0], hostInfo->h_length);
    
      int sock_id = socket(AF_INET, SOCK_STREAM, 0);
      if (sock_id == -1)
        return -1;
    
      //connect to server
      if(connect(sock_id, (struct sockaddr *) &serverAddress, sizeof(serverAddress)) < 0) {
        return -1;
      }
    
      return sock_id;
    }
    

    Der Grund warum ich nicht QSocket verwende ist da der Server bereits in C geschrieben wurde und ich zwar via QSocket Nachrichten an den Server schicken kann, jedoch keine Rückantwort vom Server kriege.

    Mit freundlichen Grüßen
    Reinhard



  • Und socket ist nicht -1 bei close?
    Hab bisher nur mit SDL_Sockets und QSockets gearbeitet, kann daher nur Vermutungen anstellen.

    Aber warum öffnest du bei jeder abgeschickten Zeile einen neuen Socket?



  • Socket ist nicht -1. Es funktioniert alles fehlerfrei, nur das Schließen bereitet mir Schwierigkeiten.

    Also der Socket wird im post-slot eines Chats verwendet, also öffne ich einen Socket sende die Anfrage und schließe ihn wieder.

    Ich bin erst kürzlich von C auf C++ umgestiegen und daher nicht vertraut mit Netzwerkkomponenten wie QSocket usw.

    Aber da die Prozedur connect_to fehlerfrei funktioniert wenn sie mit gcc kompiliert wird, verstehe ich irgndwie nicht was das Problem ist...

    Hat jemand einen Tipp? Ich bin auch mit googeln nicht weiter gekommen ..



  • Da man dann ausgehen kann das mehrere solche Nachrichten verschickt werden, solltest du den socket nur einmal öffnen und erst dann wieder schließen, wenn es auch wirklich nötig ist (Programm beenden, Serverwechsel, Abmeldung oder was auch immer).

    Du nutzt #include <sys/socket.h> für Sockets, oder?



  • Hi,
    Musst Du nicht closesocket anstelle von close verwenden?

    Was für ein OS, Complier, Library etc. verwendest Du?

    Simon



  • Ich finde beim besten Willen in der sys/socket.h keine Funktion zum Schließen von Socktes.... komisch.



  • @Fellhuhn
    Ich verstehe erlich gesagt nicht ganz wie du das meinst.

    Also auf Server seite gibt es einen socket für Requests, der mit accept auf Nachrichten wartet.
    Hingegen sollte der Client (meiner Meinung nach) nicht andauernd in Verbindung zum Server stehen. Keine Ahnung habs so gelernt und es erscheint mir Ok zu sein einen socket nur dann zu verwenden wen ich ihn wirklich brauche..

    @Simon

    Also closesocket kenne ich gar nicht und finde auch keine Man-pages darüber.
    Das close das ich verwende befindet sich in der LIb <unistd.h> und dient dazu einen Filedescriptor zu schließen, der ja bei Sockets erstellt wird.

    Also ich verwende Linux, und kompliere hier mit g++ (mir gcc funktioniert alles komischerweise)

    Verwende folgende Libs

    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <netdb.h>
    #include <pthread.h>
    #include <arpa/inet.h>
    #include <string.h>
    #include <signal.h>
    


  • Folgendes wäre schon einmal besser:

    #include <cstdio>
    #include <cstdlib>
    #include <stdbool.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <netdb.h>
    #include <pthread.h>
    #include <arpa/inet.h>
    #include <cstring>
    #include <csignal>
    

    Nun, C++ ist kein C, daher kann es da zu Problemen kommen. Und wieso funktionieren QSockets nicht? Es kommt doch das gleiche beim Server an, nur die Aufrufe sind anders (und komfortabler wie ich finde).



  • Also wie gesagt bin C++ neuling und mit C gut vertraut. Wollte einen einfachen C server der mit einem C++ client interagiert.

    Habe mich mit QSockets kurz befasst, konnte dem Server etwas via TCP schicken, konnte allerdings die Rückantwort nicht empfangen.

    Ich weiß meine Fragen sind nicht die schlausten aber ich weiß noch nicht sehr viel über C++.

    Habe bisher eine Makefile mit qmake erstellt. Habe jetzt die Libs wie beshrieben geändert, kann aber nicht mehr kompliieren.

    gcc -c -pipe -Wall -W -O2 -D_REENTRANT -DQT_NO_DEBUG -DQT_THREAD_SUPPORT -DQT_SHARED -DQT_TABLET_SUPPORT -I/usr/share/qt3/mkspecs/default -I. -I. -I/usr/include/qt3 -o networking.o networking.c
    networking.c:15:18: Fehler: cstdio: No such file or directory
    networking.c:16:19: Fehler: cstdlib: No such file or directory
    networking.c:26:19: Fehler: cstring: No such file or directory
    networking.c: In Funktion »isValidIP«:
    networking.c:104: Warnung: Implizite Deklaration der Funktion »sscanf«
    networking.c:104: Warnung: Unverträgliche implizite Deklaration der eingebauten Funktion »sscanf«
    make: *** [networking.o] Fehler 1



  • Zunächst mal zu deinem Problem:

    Die Anwendung ist singlethreaded, also KANN es passieren, daß eine Oberfläche einen Timeout hat. Das passiert beispielsweise auch, wenn du in VStudio ein Oberflächenelement debuggst, und dieses für 60 Sekunden vom System nicht aktualisiert werden kann - die Oberfläche ist dann im Timeout und man muss das System neu starten.

    Ist aber nur so ein Schuss ins Blaue.

    Noch etwas: Die Anderen haben recht: TCP Verbindungen lässt man offen, bis eine Verbindung nicht mehr benötigt wird. TCP sendet nur Pakete, wenn Daten zu übertragen sind, oder um einen Timeout zu verhindern.

    Im Übrigen lässt z.B. Windows XP zu jeder Zeit nur zwei TCP Verbindungen zwischen zwei Hosts zu. Evtl. ist die Verbindung noch nicht abgebaut, wenn du eine neue aufmachst, was beim dritten Aufruf zum Absturz führen könnte.

    Cheers
    Sid



  • rklapfer schrieb:

    Also wie gesagt bin C++ neuling und mit C gut vertraut. Wollte einen einfachen C server der mit einem C++ client interagiert.

    Habe mich mit QSockets kurz befasst, konnte dem Server etwas via TCP schicken, konnte allerdings die Rückantwort nicht empfangen.

    Ich weiß meine Fragen sind nicht die schlausten aber ich weiß noch nicht sehr viel über C++.

    Habe bisher eine Makefile mit qmake erstellt. Habe jetzt die Libs wie beshrieben geändert, kann aber nicht mehr kompliieren.

    gcc -c -pipe -Wall -W -O2 -D_REENTRANT -DQT_NO_DEBUG -DQT_THREAD_SUPPORT -DQT_SHARED -DQT_TABLET_SUPPORT -I/usr/share/qt3/mkspecs/default -I. -I. -I/usr/include/qt3 -o networking.o networking.c
    networking.c:15:18: Fehler: cstdio: No such file or directory
    networking.c:16:19: Fehler: cstdlib: No such file or directory
    networking.c:26:19: Fehler: cstring: No such file or directory
    networking.c: In Funktion »isValidIP«:
    networking.c:104: Warnung: Implizite Deklaration der Funktion »sscanf«
    networking.c:104: Warnung: Unverträgliche implizite Deklaration der eingebauten Funktion »sscanf«
    make: *** [networking.o] Fehler 1

    Wenn du C++ schreibst, muss die Quellcode-Datei auch .cpp heissen, oder du musst den Compiler anweisen, sie als CPP zu übersetzen.

    (Er findet die includes/libs nicht, weil du als C und nicht als C++ Code kompilierst)



  • P.S.: DAS müsstest du aber wissen, wenn du "mit C gut vertraut" bist.



  • Ok, war echt blöde Frage.

    Af jeden Fall herzlichen Dank, ich werde versuchen das Problem zu lösen bzw auf QSsockets umsteigen



  • Hallo

    Deine Klasse ist von QWidget abgeleitet und ich kann mir vorstellen, dass QWidget eine Methode close besitzt. Kann es sein, dass Du diese aufrufst? Das würde auch erklären, warum dann Dein QT-Fenster verschwindet. Liegt die close Funktion für die Sockets wirklich im globalen Namensraum?. Dann musst Du es so

    ::close(...
    

    aufrufen.

    DJohn



  • Ach gott, das wars!! So ein bescheuerter Fehler kann auch nur mir pasieren ...

    Danke!!!


Anmelden zum Antworten