Seite 1 von 1

QDataStream nicht blockend?

Verfasst: 17. April 2009 17:49
von luke-r2d2
Hi,

Ich habe ein Problem mit dem QDataStream um einen QTcpSocket. Im Prinzip möchte ich ein (langes) char* vom einen zum Anderen Socket schicken. Momentan nutze ich den folgenden Code:

Sender:

Code: Alles auswählen

QDataStream stream(socket);
stream << string.toAscii().data();
Empfänger (direkt von readyRead() aufgerufen):

Code: Alles auswählen

QDataStream stream(socket);
char* str;
stream >> str;
Direkt nach dem Lese-Prozess ist der String str leer (qstrlength(str) == 0). Wenn ich kurze Zeit warte, ist er mir Daten gefüllt. Sieht so aus, als ob QDataStream nicht-blockend arbeiten würde. Krieg ich das irgendwie blockierend? Ich möchte danach direkt die Daten verarbeiten...

Ciao,
Lucas

Verfasst: 17. April 2009 18:08
von solarix
ich sehe schon: die Macht ist nicht mit dir...

TCP arbeitet als "Stream", das heisst: die versendeten Daten kommen "stückchenweise" beim Client an, so dass dieser selbst prüfen muss, ob die Daten komplett sind...

Daher: du musst ein eigenes Protokoll dazu schreiben. Ein einfaches wäre, vor dem String dessen Länge (als int) zu senden. Diese Länge kannst du dann (beim ersten "readyRead()") beim Client auslesen und (allenfalls bei jedem weiteren "readyRead()") die "bytesAvailable()" auf diese Länge prüfen....

Dieses "Problem" wird etwa alle 2-3 Wochen gefragt... evt. findest du mit der Forensuche Code für ein solch primitives Protokoll...

Verfasst: 17. April 2009 18:10
von luke-r2d2
Hmm, okay, sry, wenn sich das wiederholt ;)

Aus der Doku von QDataStream habe ich nur darauf geschlossen, dass der genau das machen soll... :? Der schickt ja an sich auch die Länge des Strings mit (zumindest so wie ichs aus dem Code lesen kann). Wie ist das dann eigentlich z.B. bei Doubles, die ich über QDataStream schicke? Muss ich dann auch erst überprüfen, ob genug Daten da sind?

Verfasst: 17. April 2009 18:24
von solarix
Ich hab das noch nie mit einem QDataStream gemacht und kann daher nur die Doku lesen.. aber da steht ja deutlich (bei deinem verwendeten Kontruktor)
for reading data, you must make sure that enough data is available on the socket
oder?

Verfasst: 17. April 2009 18:26
von luke-r2d2
Okay, ich hab das hier falsch interpretiert (als ein Warten auf \0):
QDataStream & QDataStream::operator>> ( char *& s )
This is an overloaded member function, provided for convenience.
Reads the '\0'-terminated string s from the stream and returns a reference to the stream.
Trotzdem nochmal die obige Frage: Muss ich das für alle Datentypen machen? Woher weiß ich, wie viele Bytes ich genau für jeden brauche (z.b. float, double, etc)?

Verfasst: 17. April 2009 18:37
von solarix
Ich wuerde zuerst die zu versenden Daten in einem QByteArray zusammenstellen (QDataStream nicht direkt auf den Socket sondern auf ein QByteArray) und danach die Laenge (QByteArray::size()) plus Daten mittels Socket versenden. Wie du die Laenge uebermittelst (binaer (Achtung Endian), ASCII), bleibt dir ueberlassen...


[EDIT]
siehe dazu http://www.qtforum.de/forum/viewtopic.php?t=8264