Problem mit QT in heterogener Netzwerksituation
-
Hallo alle miteinander,
ich habe derzeit ein Problem (wahrscheinlich mit Qt), dass mich zur Weisglut bringt.
Ich habe einen Server in Qt und der Client ist von einem anderen Teammitglied in Visual Basic .Net geschrieben.
Der Client kann auch (relativ) problemlos meine Nachrichten empfangen, allerdings spinnt der Server beim Empfang.
Der Server verwaltet mehrere Sockets. Er erkennt richtig, auf welchem er lesen muss, ließt dann jedoch nicht, da "bytesAvailabe()" kleiner ist als blocksize.
blockSize beträgt 12539, obwohl nur 6 Zeichen in Utf8-Codierung gesendet werden. "bytesAvailabe" beträgt allerdings nur 4.
Wenn ich das gleiche mit einem Test-Client in Qt probiere, funktioniert alles (Gleicher Text wird in Utf8 gesendet, bytesAvailabe(): 10, blockSize: 10).Kann es vielleicht daran liegen, dass Qt besonders formatierte Netzwerk-Streams erwartet?
Hat jemand eine andere Erklärung für dieses Fehlverhalten?Jede Hilfe ist willkommen.
Ciao und Danke im Voraus,
Prof. MAAD
-
prof_maad schrieb:
Hallo alle miteinander,
ich habe derzeit ein Problem (wahrscheinlich mit Qt), dass mich zur Weisglut bringt.
Ich habe einen Server in Qt und der Client ist von einem anderen Teammitglied in Visual Basic .Net geschrieben.
Der Client kann auch (relativ) problemlos meine Nachrichten empfangen, allerdings spinnt der Server beim Empfang.
Der Server verwaltet mehrere Sockets. Er erkennt richtig, auf welchem er lesen muss, ließt dann jedoch nicht, da "bytesAvailabe()" kleiner ist als blocksize.
blockSize beträgt 12539, obwohl nur 6 Zeichen in Utf8-Codierung gesendet werden. "bytesAvailabe" beträgt allerdings nur 4.
Wenn ich das gleiche mit einem Test-Client in Qt probiere, funktioniert alles (Gleicher Text wird in Utf8 gesendet, bytesAvailabe(): 10, blockSize: 10).Kann es vielleicht daran liegen, dass Qt besonders formatierte Netzwerk-Streams erwartet?
Hat jemand eine andere Erklärung für dieses Fehlverhalten?Jede Hilfe ist willkommen.
Ciao und Danke im Voraus,
Prof. MAAD
Vielleicht solltest du mal in beiden Fällen mit einem Sniffer das Netzwerk belauschen, um zu sehen, was tatsächlich über die Leitung geht und wie sich beide Fälle unterscheiden.
Ich würde dir Ethereal empfehlen. Als Filter nimmst du "tcp port <euer port>". Das Logfile kannst du dann analysieren oder hier posten.
-
Danke erstmal alle miteinander,
wir haben das Problem nun durch Analyse des Netzwerkverkehrs gelöst.
Dadurch haben wir eine Art Header bei Qt-Netzwerkübertragungen entdeckt:
Er besteht aus 6 Bytes:
2 Bytes Gesamtstreamlänge (exklusive den 2 "LeerBytes" - also im Endeffekt Länge der Daten + 4 Bytes)
2 Bytes 0 (l"LeerBytes")
2 Bytes Länge der Daten (exklusive Header)Die Längen sind mit einem Zahlensystem mit 256 als Basis angegeben. Das heißt, dass 1|0 entspricht 256 in Dezimal.
So, vielleicht hilft das ja anderen, die ähnliche Probleme in heterogenen Netzwerksituationen mit Qt haben.
Danke und Ciao,
Prof. MAAD
-
prof_maad schrieb:
Danke erstmal alle miteinander,
wir haben das Problem nun durch Analyse des Netzwerkverkehrs gelöst.
Dadurch haben wir eine Art Header bei Qt-Netzwerkübertragungen entdeckt:
Er besteht aus 6 Bytes:
2 Bytes Gesamtstreamlänge (exklusive den 2 "LeerBytes" - also im Endeffekt Länge der Daten + 4 Bytes)
2 Bytes 0 (l"LeerBytes")
2 Bytes Länge der Daten (exklusive Header)Die Längen sind mit einem Zahlensystem mit 256 als Basis angegeben. Das heißt, dass 1|0 entspricht 256 in Dezimal.
So, vielleicht hilft das ja anderen, die ähnliche Probleme in heterogenen Netzwerksituationen mit Qt haben.
Danke und Ciao,
Prof. MAAD
Das kann nicht sein. Qt schickt nicht einfach so Header über das Netzwerk. Was macht ihr genau?
-
Ich hätte auch gedacht, dass es das nicht tut, aber es scheint so zu sein.
Hier ein Code-Fragment der Sende-Funktion des Servers:
bool OES::sendString(QString toSend, int clientNumber) { QByteArray block; QDataStream out(&block, QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_4_0); out <<(quint16)0; toSend += NetString_End; out << toSend.toUtf8(); out.device()->seek(0); out << (quint16)(block.size() - sizeof(quint16)); clients->at(clientNumber)->socket->write(block); return true; }
Über diese Funktion werden alle Netzwerkübertragungen des Servers getätigt.
Falls jemand eine Idee hat, wieso Qt einen Header mitschickt, wäre ich sehr interessiert.
Ciao,
Prof. MAAD
-
Ist ja kein Wunder. Ihr benutzt die Serialisierung von Qt mittels QDataStream. Das ist Qt spezifisch und kann nur von Qt wieder dekodiert werden.
Das ist nur dazu gedacht, zwischen Qt Anwendungen zu kommunizieren. Ihr wollt doch bestimmt was ganz anderes. Wie sieht euer Protokoll aus?
-
Danke erstmal für diese Info.
Ich habe meine Qt-Erfahrungen fast alle aus der Doku, und dort benutzen alle Netzwerk-Anwendungen diese Technik (sind ja auch alle Qt-Only).
Unser Protokoll besteht aus 3 Teilen:
Befehl (2 Ints) + ClientID(4 Ints) + Parameter (String)Beispiel:
120000 1 (Befehl: 12, ID: 0000, Parameter: 1)Das System besteht aus einem Server in Qt und einem Client in VB.Net.
Diese kommunizieren über das oben angegebene Protokoll.Wie bekomme ich ein QByteArray, ohne diese Qt-spezifischen Header?
Ich bin dankbar für jede Hilfe.
Danke im Voraus und Ciao,
Prof. MAAD
-
prof_maad schrieb:
Danke erstmal für diese Info.
Ich habe meine Qt-Erfahrungen fast alle aus der Doku, und dort benutzen alle Netzwerk-Anwendungen diese Technik (sind ja auch alle Qt-Only).
Unser Protokoll besteht aus 3 Teilen:
Befehl (2 Ints) + ClientID(4 Ints) + Parameter (String)Beispiel:
120000 1 (Befehl: 12, ID: 0000, Parameter: 1)Das System besteht aus einem Server in Qt und einem Client in VB.Net.
Diese kommunizieren über das oben angegebene Protokoll.Wie bekomme ich ein QByteArray, ohne diese Qt-spezifischen Header?
Ich bin dankbar für jede Hilfe.
Danke im Voraus und Ciao,
Prof. MAAD
Was ist bei euch ein Int? Ein Zeichen zwischen 0 und 9? Wie sind die Strings kodiert? ASCII, ISO 8859-1, UTF-8, UTF-16? Für UTF-8 liefert QString::toUtf8() zum Beispiel ein QByteArray in dieser Kodierung. Da sind dann keine Serialisierungsheader drin.
-
Danke erstmal für den Tip.
Also, dass was ich als Int bezeichnet habe, ist letztendlich eine Zahl zwischen 0 und 9.
Letztendlich wird das gesamte zu Übertragende in einen QString gepackt und dann der Funktion sendString(QString toSend) [siehe Unten] übergeben.
Diese wandelt ihn dann in UTF-8-Codierung um und schreibt ihn per QDataStream in ein Byte-Array, welches dasnn versendet wird.Wenn ich deinen Tip richtig verstanden habe, könnte ich das also auch so erledigen:
bool OES::sendString(QString toSend, int clientNumber) { QByteArray block; toSend += NetString_End; block = toSend.toUtf8(); clients->at(clientNumber)->socket->write(block); return true; }
Ist dass so möglich, und erhalte ich dadurch eine Netzwerkübertragung, die keine Qt-spezifischen Header enthält?
Danke im Voraus für alle Antworten.
Ciao,
Prof. MAAD
-
Ich denke schon.