Seite 1 von 1
Qt Network
Verfasst: 24. November 2010 13:17
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
Verfasst: 24. November 2010 13:31
von Christian81
Verfasst: 24. November 2010 18:51
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?
Verfasst: 24. November 2010 20:24
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.
Verfasst: 24. November 2010 22:40
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
Verfasst: 30. November 2010 13:27
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
Verfasst: 30. November 2010 13:57
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!
Verfasst: 30. November 2010 14:02
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

Verfasst: 14. Dezember 2010 19:43
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
Verfasst: 15. Dezember 2010 08:37
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.
Verfasst: 17. Dezember 2010 18:25
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);
}
Verfasst: 20. Dezember 2010 10:35
von pfid
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.