(gelöst) QT 4.5: QTcpSocket bekommt kein readyRead()
-
Hallo Zusammen,
ich habe eine Client Server Verbindung, welche folgenden Datenverkehr hat.
Client Server
<Request> -> )- Listen
WaitofData <- Answer
Hierbei arbeitet der der Server korrekt,
er erhält das Anforderungstelegram und anwortet auch.Nur bekommt der Client kein readyRead() Signal()...
tcpSocket = new QTcpSocket(); connect(tcpSocket, SIGNAL(disconnected()), this, SLOT(ConnectionClosedFromServer())); connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readDataFromServer())); tcpSocket->connectToHost(ServerName,PORT_OF_IO_TASK); tcpSocket->waitForConnected(5000); if (tcpSocket->state() == QAbstractSocket::ConnectedState) { QDataStream Communication(&block, QIODevice::WriteOnly); Communication.setVersion(QDataStream::Qt_4_5); Communication << (quint16)0; Communication << tr("R") << ActualDB ; Communication.device()->seek(0); Communication << (quint16)(block.size() - sizeof(quint16)); tcpSocket->write(block); tcpSocket->waitForBytesWritten(5000); WaitForEndofTransmission= true; }
Hat jemand eine Idee wie ich den Fehler eingrenzen oder gar finden kann.
edit 1:
Weitere Infos vom Debuggen:
Der Server beendet die Verbindung korrekt nach dem er de Daten gesendet hat.
Der Socketstatus geht auf closed !Der Client haelt weiterhin einen Socket aufrecht ? Mit wem weiss ich jedoch noch nicht.
Der Server ist ein Threaded Server.edit 2:
Es scheint mir so, also ob keine Signals gesendet werden, da ich jetzt auch Connect als Signal geschrieben habe. Und einen QDebug() in alle Signals gesetzt habe. keiner wird ausgeführt.edit 3:
Signals werden doch erzeugt. Nur nicht in der korrekten Abfolge. Hier scheint das nicht wirklich synchron zu laufen. Der Fehler kann jetzt also am Client und oder Server liegen ...Gruss
-
Hi,
ich versuche jetzt einen anderen Ansatz und habe hier das Problem,
das ich mittels des QTcpServer nach dem Connect erstmal eine
Verbindug aufbaue und mir das Kommando abhole und dieses dem Thread als Auftrag mitgebe.Ich habe das Beispiel für von QT FortuneServer angepasst, damit ich die Sache gezielt bearbeiten kann.
Mein Problem liegt jetzt im Einlesen des Kommandos auf der Serverseite, da QTcpServer kein Verbindungsobjekt hat. Erstelle ich mir ein Socket mit Descriptor
bekomme ich zwar ein Signal "ReadReady()". Aber bei dem Zugriff auf "->bytesAvailable() " ist er weg .Hier der Code:
FortuneServer::FortuneServer(QObject *parent) : QTcpServer(parent) { } void FortuneServer::readCommandData(void) { int NewData; qDebug() << "readCommandData entered after readReady() " ; QDataStream in(clientConnection); in.setVersion(QDataStream::Qt_4_0); qDebug() << "Socket State : " << clientConnection->state(); if (blockSize == 0) { NewData=clientConnection->bytesAvailable(); if (NewData < (int)sizeof(quint16)) return; in >> blockSize; } if (clientConnection->bytesAvailable() < blockSize) return; in >> Command; qDebug() << "Receive command " << Command; FortuneThread *thread = new FortuneThread(clientConnection->socketDescriptor(), Command, this); connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); thread->start(); delete clientConnection; } void FortuneServer::incomingConnection(int socketDescriptor) { blockSize=0; QTcpSocket *clientConnection = new QTcpSocket; if (clientConnection->setSocketDescriptor(socketDescriptor) == false) { return; } qDebug() << "Incoming Socket State : " << clientConnection->state(); connect(clientConnection, SIGNAL(readyRead()), this, SLOT(readCommandData())); qDebug() << "Incomming Connection from client "; }
Hier die Def.:
class FortuneThread : public QThread { Q_OBJECT public: FortuneThread(int socketDescriptor, const QString &toDo, QObject *parent); void run(); private slots: void DisconnectFromClient(); signals: void error(QTcpSocket::SocketError socketError); private: int socketDescriptor;; QString Command; };
Der Debugger bleibt in dieser Routine hängen
NewData=clientConnection->bytesAvailable();
es gibt folgende Ausgabe durch qDebug, was ich mir nicht erklären kann:
Incoming Socket State : QAbstractSocket::ConnectedState
Socket Descriptor : 16
Incomming Connection from client
readCommandData entered after readReady()
Socket State : QAbstractSocket::UnconnectedState
Socket Descriptor : 134549416Hat jemand eine Idee wieso ?
Wie kann ich innerhalb des QTCPServer erstmal eine Verbindung aufbauen und das Kommando einlesen. Ist hier der Fehler ?
Gruss
-
Hallo Zusammen,
einen Threaded Server mit Signals Slots habe ich nicht hin bekommen.
Da habe ich eben Threaded blocked verwendet. Der scheint stabil zu arbeiten.
Hier der Code für andere
FortuneServer::FortuneServer(QObject *parent) : QTcpServer(parent) { } void FortuneServer::incomingConnection(int socketDescriptor) { qDebug() << "Server: incomingConnection() Create thread " ; FortuneThread *thread = new FortuneThread(socketDescriptor); connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); thread->start(); } FortuneThread::FortuneThread(int socketDescriptor) : socketDescriptor(socketDescriptor) { } void FortuneThread::run() { QString Command; QTcpSocket tcpSocket; quint16 blockSize; if (tcpSocket.setSocketDescriptor(socketDescriptor) == false) { emit error(tcpSocket.error()); return; } QDataStream in(&tcpSocket); in.setVersion(QDataStream::Qt_4_0); while ( tcpSocket.bytesAvailable() < (int)sizeof(quint16) ) { if ( tcpSocket.waitForReadyRead(200) == false) { emit error(tcpSocket.error()); } } in >> blockSize; while ( tcpSocket.bytesAvailable() < (int) blockSize ) { if ( tcpSocket.waitForReadyRead(200) == false) { emit error(tcpSocket.error()); } } in >> Command; QString Message; Message=tr("You just send the command %1 to the server").arg(Command); QByteArray block; QDataStream out(&block, QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_4_0); out << (quint16)0; out << Message; out.device()->seek(0); out << (quint16)(block.size() - sizeof(quint16)); tcpSocket.write(block); tcpSocket.waitForBytesWritten(2000); tcpSocket.close(); }
Gruss
P.S.: Wenn jemand einer Threaded Lösung mit Slots für ReadyRead hat, bitte posten