(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 : 134549416

    Hat 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


Anmelden zum Antworten