Qt Network
Qt Network
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
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:
Ich schätze das hilft: http://doc.trolltech.com/4.6/qtnetwork.html#details
MfG Christian
'Funktioniert nicht' ist keine Fehlerbeschreibung
'Funktioniert nicht' ist keine Fehlerbeschreibung
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.
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.
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
client.cpp
gamescreen.cpp
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
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
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!
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!
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
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
Klar.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.
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
}
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:
aufruf der methode beim empfangen des Buchstabens:
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;
}
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);
}
Sofern m_word ein QString ist:
Wäre ein
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.
Wäre ein
Code: Alles auswählen
if (m_word.indexOf(_guess) == -1)
m_counter--;
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.