[GELÖST] TCP - empfange manchmal leere Pakete

Alles rund um die Programmierung mit Qt
Antworten
th3AddY
Beiträge: 11
Registriert: 7. Februar 2013 07:07

[GELÖST] TCP - empfange manchmal leere Pakete

Beitrag von th3AddY »

Hallo,

Ich möchte eine Client-Server Kommunikation über TCP implementieren. Dabei erstellt der Server für jeden neuen Client einen eigenen Thread um mit ihm zu kommunizieren.
Verbindet sich ein Client mit dem Server, erhalte ich vom QTcpServer im Hauptthread einen Zeiger auf den QTcpSocket. Diesen übergebe ich an den jeweiligen Client-Thread über den Socketdeskriptor.

Innerhalb von run() des QThread:

Code: Alles auswählen

m_socket = new QTcpSocket();
m_socket->setSocketDescriptor(m_descriptor);
Das Senden an den Client passiert weiterhin im Hauptthread über den Socket, den ich vom QTcpServer erhalten habe.

Der Client funktioniert ähnlich. Er nutzt auch einen Thread (Klasse TcpThread), der für die Tcp Kommunikation zuständig ist.

Innerhalb von run() des QThread:

Code: Alles auswählen

m_socket = new QTcpSocket();
m_socket->connectToHost(m_hostName, m_port);
Das Senden an den Server passiert hier ebenfalls im Hauptthread, wobei der Client via TcpThread::getSender() den Socket erhält.

Code: Alles auswählen

QTcpSocket* TcpThread::getSender()
{
	if (m_sender==NULL)
	{
		m_sender = new QTcpSocket();
		m_sender->setSocketDescriptor(m_socket->socketDescriptor());
	}

	return m_sender;
}
Das Empfangen von Daten funktioniert sowohl beim Server, als auch beim Client schematisch folgendermaßen:

Code: Alles auswählen

while (!m_error)
{
	if (m_socket->waitForReadyRead())
	{
		QByteArray data = m_socket->readAll();
		emit receive(data);
	}
}
Sobald der Thread Daten vom Socket erhält, wird ein Signal gefeuert, um es dem Client bzw. Server mitzuteilen.
Die Threads sind sozusagen die meiste Zeit im wait Zustand und dafür zuständig, Daten zu empfangen.

Das funktioniert in den meisten Fällen wunderbar, jedoch nicht immer. Manchmal empfange ich leere Pakete (0 bytes).
Dies passiert in etwa 10-20% aller Fälle wenn ich vom Client zum Server sende.

Ich bin echt ratlos und weiß nicht, woran es liegen könnte. Es wird zwar etwas empfangen, jedoch nur "leere" Daten. Und das völlig willkürlich.

Ich wär Euch echt sehr dankbar, wenn ihr mir dabei helfen könnt.

Viele Grüße,
Daniel
Zuletzt geändert von th3AddY am 14. Februar 2013 02:14, insgesamt 1-mal geändert.
odt
Beiträge: 128
Registriert: 12. August 2010 11:49
Kontaktdaten:

Re: TCP - empfange manchmal leere Pakete

Beitrag von odt »

Hallo Daniel

Wirklich helfen kann ich zwar nicht, aber ein zwei Trivialfragen und Gedankenanstösse...

Kommen alle Daten an?
Schickst Du ein leeres QByteArray?
Wer ist der Owner des Sockets? Welcher Thread ruft getSender auf?
Machst Du zwei QTcpSockets für einen Socket-Descriptor? (Phu, gefühlsmässig: dont do that! Im Hintergrund zwei SysCall's = zwei Events?)
QTcpSocket ist nicht thread-safe.
Grundsätzlich frage ich mich aber, warum Du überhaupt Threads verwendest. Sockets sind ja schon nicht-blockierend. Dein Thread scheint nur ein readyread-Signal zu simulieren.

Viele Grüsse
Reto
ODT Informatik GmbH, Reto Tschofenig
th3AddY
Beiträge: 11
Registriert: 7. Februar 2013 07:07

Re: TCP - empfange manchmal leere Pakete

Beitrag von th3AddY »

Ich bekomme jedes mal das receive-event wenn ich Daten schicke, jedoch sind diese in manchen Fällen leer obwohl ich keine leeren QByteArrays schicke.

Auf Client-Seite wird der QTcpSocket im TcpThread-Kontext erstellt. Zum Senden rufe ich vom Hauptthread die getSender() Methode auf, um von hier aus Daten senden zu können. Dabei wird ein neuer QTcpSocket erstellt, dem der Deskriptor des Sockets aus dem TcpThread zugewiesen wird. Nur so kann ich über die Threads hinweg diesen Socket nutzen.

Auf Server-Seite ist es ähnlich. Dort bekomme ich den QTcpSocket im Hauptthread vom QTcpServer und gebe dessen Deskriptor an den TcpThread, um dort einen neuen QTcpSocket zu erstellen, den ich dort nutzen kann. Zum senden verwende ich einfach den Socket, den ich vom QTcpServer im Hauptthread erhalten habe.

Es ist nun eine Überlegung wert, das Thread-Gedöns sein zu lassen und einfach das receive-Event vom QTcpSocket zu nutzen um Daten zu empfangen. Aber ich kann mir trotzdem nicht erklären, warum ich leere Daten erhalte, OBWOHL ich niemals leere Daten sende.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Re: TCP - empfange manchmal leere Pakete

Beitrag von Christian81 »

Ein senden impliziert nicht immer ein empfangen. Du musst überprüfen was für Daten ankommen - nimm den Thread raus und warte auf readyRead(). Lies dann die Daten aus und parse sie korrekt.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
th3AddY
Beiträge: 11
Registriert: 7. Februar 2013 07:07

Re: TCP - empfange manchmal leere Pakete

Beitrag von th3AddY »

Ich hab die Threads herausgenommen und jetzt funktioniert es.
Vielen Dank für die Hilfe.
Antworten