Qt Network

Alles rund um die Programmierung mit Qt
Antworten
Meli90
Beiträge: 6
Registriert: 15. November 2010 13:55

Qt Network

Beitrag von Meli90 »

Hallo!

Ich möchte im Rahmen meines Unterrichts ein Hangman-Spiel programmieren, dass mit einem n900 übers Wlan spielbar ist.

Jetzt wollte ich versuchen die Kommunikation zwischen Server und Client so zu implementieren wie ich es zuvor schon für einen C++ Server/Client gemacht habe.
Habe es auch schon implementiert aber ich bekomme beim ausführen von Client und Server folgenden Fehler: Collect2: ld returned 1 exit status

Jetzt wollte ich nachfragen, ob das überhaupt möglich ist oder ob ich die Qt Klassen dafür verwenden muss.


Client.h -> http://pastebin.com/sv9s1uD6
Client.cpp -> http://pastebin.com/WUJwrkyp

Server.h -> http://pastebin.com/djEErn3K
Server.cpp -> http://pastebin.com/HpaCGm4P


Hoffe ihr könnt mir helfen!

Lg
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
Meli90
Beiträge: 6
Registriert: 15. November 2010 13:55

Beitrag von Meli90 »

das jetzt soviel heißt wie: ich muss die eigenen Qt Klassen verwenden und kann das Beispiel nicht 1:1 von c++ übernehmen?
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Deine Meldung bringt einen nicht weiter. Das ist nur der finale Statusbericht von ld (btw. nicht "Ausführen"), dass etwas nicht passt. undefined reference, file not found, usw.
Wenn du die Meldung posten würdest könnte man auch besser helfen.

Und nein, du musst nicht auf die QtNetwork-Sachen ausweichen. Es wäre aber sehr praktisch, da dort Netzwerk nicht nur auf Windows funktioniert, sondern auf allen Plattformen. Mit deinem WinSock gehts halt mal nur auf Windows.
dazedly
Beiträge: 197
Registriert: 3. Oktober 2010 15:38
Kontaktdaten:

Beitrag von dazedly »

Meli90 hat geschrieben:das jetzt soviel heißt wie: ich muss die eigenen Qt Klassen verwenden und kann das Beispiel nicht 1:1 von c++ übernehmen?
Ich glaube er meinte wohl eher den Hinweis weiter unten:
To link against the module, add this line to your qmake .pro file:
QT += network
Meli90
Beiträge: 6
Registriert: 15. November 2010 13:55

Beitrag von Meli90 »

so ich habe nun alles komplett umgebaut und es funktioniert nun alles auch soweit...nun möchte ich von dem Fenster in dem ich mich vom Client zum Server verbinde den QTcpSocket an den Gamescreen(den kann ich nach dem verbinden öffnen) übergeben, damit ich noch Zugriff darauf habe und im gamescreen auch etwas an den Server senden kann.

gekürzter Code:
client.h

Code: Alles auswählen

#ifndef CLIENT_H
#define CLIENT_H

#include <QWidget>
#include <QtNetwork>
#include <QString>
#include <QTcpSocket>
#include "gamescreen.h"

namespace Ui {
    class Client;
}

class Client : public QWidget
{
    Q_OBJECT

public:
    explicit Client(QWidget *parent = 0);
    ~Client();
    QTcpSocket client;

public slots:
     void openGameScreen();
     void enableConnectButton();
     void enableStartButton();

    void connectToServer();
    //void startPrint();


private:
    Ui::Client *ui;
    quint16 port;
};

#endif // CLIENT_H


client.cpp

Code: Alles auswählen

...
connect(ui->connectButton,SIGNAL(clicked()),this,SLOT(connectToServer()));
connect(&client,SIGNAL(connected()),this,SLOT(openGameScreen()));

void Client::connectToServer(){

    QString address = ui->IpText->text();
    QHostAddress addr(address);
    client.connectToHost(addr,8888);
    ui->connectButton->setEnabled(false);
}

void Client::openGameScreen() {
    enableStartButton();
    GameScreen game;
    game.setTcpSocket(client);
    game.show();
}
...

gamescreen.cpp

Code: Alles auswählen

...
void GameScreen::setTcpSocket(QTcpSocket clientsocket){
    client = clientsocket;
}


Fehlermeldung bei Aufruf in der client.cpp Klasse in der Methode openGameScreen():
game.setTcpSocket(client);

-> QTcpSocket::QTcpSocket(const QTcpSocket&) is private


Hat jemand eine Ahnung was das sein könnte? Die Fehlermeldung erscheint direkt in der QTcpSocket Klasse...wie umgehe ich das? bzw wie muss ich das Programm umschreiben, damit ich noch zugriff auf meine Verbindung habe?


LG
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag von solarix »

Vielleicht solltest du noch etwas an den C++-Grundlagen feilen...

Was du versuchst ist, eine Kopie (Call-By-Value) der Socket-Verbindung anzulegen. Das sieht Qt so nicht vor (zwei Socket-Instanzen auf eine Connection...?). Was du vermutlich eher moechtest, ist die Instanz nicht zu Kopieren, sondern als Pointer der "game"-Instanz zu uebergeben ("void GameScreen::setTcpSocket(QTcpSocket *clientsocket)").

Aus OOP-Sicht duerfte das Projekt auch problematisch werden, weil ich da keine Strategie sehe (z.B. wer der "Kontroller" der TCP-Verbindung ist). Ich habe den Verdacht, dass du mit der public-Instanz ein "jeder ist Kontroller"-Konzept verfolgst und damit frueher oder spaeter (eher frueher) Probleme bekommen wirst..

hth!
Meli90
Beiträge: 6
Registriert: 15. November 2010 13:55

Beitrag von Meli90 »

ah genau stimmt....danke

programmier erst seit 4 Wochen ca C++, da hat man diese Sachen noch nicht so intus, vorallem wenn man vorher Java programmiert hat ;)
Meli90
Beiträge: 6
Registriert: 15. November 2010 13:55

Beitrag von Meli90 »

So nach vielen,vielen Problemen bin ich nun fast fertig.

Hätte aber noch ein paar Fragen:

Kann ich irgendwie meinen TCPsocket den ich in der 1.Form erstelle dann an eine 2. Form übergeben? Sprich ich erstelle die Verbindung zum Server im Startbildschirm, sobald das geschehen ist, öffne ich einen Spielebildschirm und diesem muss ich natürlich meinen TCPsocket übergeben, damit ich wieder Zugriff auf meine Verbindung habe....das klappt aber irgendwie nicht so wie ich mir das vorgestellt habe. Hätte es ganz normal per Konstruktor übergeben -> geht aber nicht.

Nun hätte ich das Programm komplett umgebaut und einfach den Spielbildschirm von Anfang an angezeigt, und einfach eine Messagebox erstellt, in der die IP adresse einzugeben ist, mit dem Klick auf "Ok" wird verbunden .... nächstes Problem ---> der Qt Simulator fürs N900 zeigt mir diese Messagebox einfach nicht an...

Jemand irgendwelche Tipps die mir da weiterhelfen könnten?

LG
pfid
Beiträge: 535
Registriert: 22. Februar 2008 16:59

Beitrag von pfid »

Meli90 hat geschrieben: Kann ich irgendwie meinen TCPsocket den ich in der 1.Form erstelle dann an eine 2. Form übergeben? Sprich ich erstelle die Verbindung zum Server im Startbildschirm, sobald das geschehen ist, öffne ich einen Spielebildschirm und diesem muss ich natürlich meinen TCPsocket übergeben, damit ich wieder Zugriff auf meine Verbindung habe....das klappt aber irgendwie nicht so wie ich mir das vorgestellt habe. Hätte es ganz normal per Konstruktor übergeben -> geht aber nicht.
Klar.

Code: Alles auswählen


class Foo : public QMainWindow
{
   public:

     Foo(QWidget* parent, QTcpSocket* s)                       // möglichkeit 1
       : QMainWindow(parent) 
      { 
         socket= s; 
      }

      void setSocket(QTcpSocket* s)                                 // möglichkeit 2
      { 
         socket= s; 
      }

   private:

      QTcpSocket* socket;
};


Irgendwo:


void Bar::newFoo()
{
   Foo* foo= new Foo(this, mySocket);           // möglichkeit 1

   foo->setSocket(mySocket);                         // möglichkeit 2
}
Der Einfachheit halber ist die Klasse oben inline implementiert. Vermutlich hast du gelernt dass in der Header-Datei die Klassendefinition und in der C-Datei die Implementierung stehen soll, das hab ich hier zusammengefasst.
Meli90
Beiträge: 6
Registriert: 15. November 2010 13:55

Beitrag von Meli90 »

danke für den tipp ;)

Das Programm ist jetzt eigentlich fertig, nur habe ich nun das Problem dass die Abfrage des Wortes nicht so passt wie ich das will. Dh auf ClientSeite wird ein Buchstabe geraten und auf Serverseite wird geschaut ob der Buchstabe im Wort drin ist.das funktioniert auch aber er zählt die Versuche nicht richtig runter. Habe mir einen counter angelegt der eigentlich runterzählen soll, wenn ein Buchstabe falsch geraten wurde.

habe mit meinem code aber das problem, dass er in der 1.Runde 1 runterzählt, in der 2. 2 usw ...ich komm einfach nicht drauf warum...
wie wenn er die methode einfach öfter aufrufen würde....ABER zu Testzwecken habe ich die if - Abfrage so geschrieben, dass runtergezählt wird, wenn richtig geraten wurde:
if(found)
{
m_counter--;
}


das funktioniert einwandfrei, wird richtig um 1 runtergezählt wenn richtig geraten wurde, da das natürlich falsch ist kann ichs so nicht lassen ;)

mein code:

Code: Alles auswählen

bool Word::makeGuess(QChar _guess)
{
    bool found = false;
    for(int i = 0; i<m_word.size(); i++)
    {
        if(m_word[i].getLetter() == _guess )
        {
            m_word[i].setStatus(true);
            found = true;


        }
    }

    if(!found)
    {
        m_counter--;
    }



return false;
}
aufruf der methode beim empfangen des Buchstabens:

Code: Alles auswählen

void Server::startRead()
{
     QString msg = client->read(10);
     QString  temp(msg);
     m_word.makeGuess(temp[0]);
     ui->label->setText("User guessed: " + temp);
}
pfid
Beiträge: 535
Registriert: 22. Februar 2008 16:59

Beitrag von pfid »

Sofern m_word ein QString ist:

Wäre ein

Code: Alles auswählen

if (m_word.indexOf(_guess) == -1)
   m_counter--;
nicht einfacher? ;) (http://doc.qt.nokia.com/4.7/qstring.html#indexOf-3)

Davon ab ist da zu wenig Code, bzw ich verstehe das Problem nicht. Eventuell solltest du auf Client und Server-Seite ein paar qDebug()s verstreuen, damit du siehst wo das problem herkommt.
Antworten