QTcpServer empfängt keine Zeichen

Alles rund um die Programmierung mit Qt
Antworten
Gorion
Beiträge: 12
Registriert: 29. Mai 2009 13:10
Kontaktdaten:

QTcpServer empfängt keine Zeichen

Beitrag von Gorion »

Hi folks,

Ich bin dabei ein Programm zu schreiben, das Zeichenketten von einem Socket runterliest und diese zur Aktualisierung von Labels in meiner Gui-Klasse verwendet.
Der Server läuft in einem Thread, der Client kann sich zum Server connecten und Datenaustausch findet auch statt. Nur bekomme ich nicht die Zeichenkette, die der Testclient sendet, sondern nichts!

Hier der Client-Code:

Code: Alles auswählen

client.h
#include <QtNetwork>
#include <QObject>
#include <QString>
#include <QTcpSocket>

class Client: public QObject
{
Q_OBJECT
public:
  Client(QObject* parent = 0);
  ~Client();
  void start(QString address, quint16 port);
public slots:
  void startTransfer();
private:
  QTcpSocket client;
};

client.cpp
#include "client.h"
#include <QHostAddress>

Client::Client(QObject* parent): QObject(parent)
{
  connect(&client, SIGNAL(connected()),
    this, SLOT(startTransfer()));
}

Client::~Client()
{
  client.close();
}

void Client::start(QString address, quint16 port)
{
  QHostAddress addr(address);
  client.connectToHost(addr, port);
}

void Client::startTransfer()
{
  client.write("Hello, world", 13);
}

main.cpp
#include "client.h"
#include <QApplication>

int main(int argc, char** argv)
{
  QApplication app(argc, argv);

  Client client;
  client.start("127.0.0.1", 59001);

  return app.exec();
}
Hier Teile meines Server-Codes:

Code: Alles auswählen

Listen-Aufruf QTcpServer Objekt:

   if (!Server.listen(QHostAddress::QHostAddress(address), port)) {
    QMessageBox::critical(this, tr("KlingelFeld Server"),
                                tr("Unable to start the server: %1.")
                                .arg(Server.errorString()));
        close();
        return;
    }
    //else
    //    newConnection();

Connect und Slot newConnection:

connect(&Server,SIGNAL(newConnection()),this,SLOT(newConnection()));

void KlingelFeld::newConnection()
{
    int socketDescriptor;
    if (!(socketDescriptor=Server.socketDescriptor())) {
        cout<<"Socketdeskripor wrong:"<<socketDescriptor<<endl;
        return;
    }
    cout<<"Socketdeskriptor new:"<<socketDescriptor<<endl;
    Thread.newConnection(socketDescriptor);
}

Methode newConnection(int socketDescriptor) der Thread-Klasse:
(hier wird das eigentliche Socketverhalten gemacht)

void KlingelFeldThread::newConnection(int socketDescriptor)
{
    QMutexLocker locker(&mutex);
    cout<<"Thread noch nicht gestartet"<<endl;
    this->socketDescriptor=socketDescriptor;
    cout<<"Socketdeskriptor:"<<socketDescriptor<<endl;
    quit=false;
    if (!isRunning()){
       start();
       cout<<"Thread gestartet"<<endl;
    }
    else
         cond.wakeOne();
}

Teile der run()-Methode:
    while (!quit) {

        const int Timeout = 5 * 1000;
        cout<<"Timeout setzen"<<endl;
        //QTcpSocket socket;

        QTcpSocket socket;
        cout<<"Socket anlegen mit Socketdescriptor:"<<socketDescriptor<<endl;
        if (!socket.setSocketDescriptor(socketDescriptor)) {
            emit error(socket.error(), socket.errorString());
            cout<<"Socket Fehler 1"<<endl;
            return;
        }

        if (!socket.waitForConnected(Timeout)) {
            emit error(socket.error(), socket.errorString());
            return;
        }
        cout<<"Socketdescriptor weitergeben"<<endl;

        mutex.lock();
        QString text, sockText;
        sockText = startReadSocket();

Methode QString startReadSocket():
QString KlingelFeldThread::startReadSocket(){
    char buffer[1024] = {0};
    QString text;
    cout<<"startReadSocket: Text einlesen"<<endl;
    socket.read(buffer, socket.bytesAvailable());
    cout << buffer << endl;
    text=QString::QString(buffer);

    return text;
}
Eigentlich sollte startReadSocket() den vom Socket heruntergelesenen Buffer auf stdout raussschreiben zur Kontrolle, da bekomme ich aber nur ne leere Zeile.
Kann mir jmnd sagen woran es liegen könnte?

Gruss Michael
Mani99
Beiträge: 244
Registriert: 15. April 2009 10:46
Wohnort: München

Beitrag von Mani99 »

Ich würde vorschlagen du siehst dir die doku zu QTcpServer sowie die beispiele dazu an. Ganz besoners zum Threaded Fortune Server, der macht nämlich genau das was du willst!

Als stichwort würde dir zu dem signal "readReady" raten, denn woher weißt du das dein socket schon bereit ist?

Und ich würds eher so machen:

Code: Alles auswählen

void DeineKlasse::newConnection(...)
{
   //....
    connect(tcpSocket,SIGNAL(readReay(),this,SLOT(receiveData));
   //....
}

void DeineKlass::receiveData()
{
//tcpSocket ist hier der pointer auf deinen socket.

QByteArray out_data;
quint16 data_sz;

QDataStream out(tcpSocket);
out.setVersion(...) //deine version der verbindung

out>>data_sz>>out_data;

cout<<out_data<<endl;
}
Das sollte eigentlich das machen was du möchtest, ist alles ungetestet!
Gorion
Beiträge: 12
Registriert: 29. Mai 2009 13:10
Kontaktdaten:

Beitrag von Gorion »

Danke,

nun habbich aber weiterhin das Problem, dass der client später durch einen C-Client ersetzt werden muss. Deshalb habe ich die read-Methode gewählt...

Was aber das Slot-Handling angeht ist es durchaus überlegenswert erst den Slot aufzurufen, wenn Daten auf dem Socket sind! Das ist nicht ganz unrichtig. Werd ich mal probieren!

Grüssle Michael
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag von solarix »

Gorion hat geschrieben: nun habbich aber weiterhin das Problem, dass der client später durch einen C-Client ersetzt werden muss. Deshalb habe ich die read-Methode gewählt...
Ist doch egal, ob der Client in C, Ada, Java, Perl, PHP oder sonst was programmiert ist: Der Server braucht in deinem Fall nicht mal ein (weiterer) Thread (QTcpSocket erstellt ja extra bereits einer). Daher könntest du dir den ganzen while-quit-mutex-Kram sparen...
Gorion
Beiträge: 12
Registriert: 29. Mai 2009 13:10
Kontaktdaten:

Beitrag von Gorion »

Dieser Thread kann als gelöst angesehen werden. Habe den Thread Kram rausgeschmissen und siehe das es funzt auch mit C-Client.
Gruss Michael

Denke das hat irgendwie Probleme mit den Objekten gegeben, dass der Socket nicht auf das richtige Objekt angesetzt war....
Antworten