[gelöst] QSocket- QDataStream

Alles rund um die Programmierung mit Qt
Antworten
stonecold
Beiträge: 147
Registriert: 19. Oktober 2005 10:48

[gelöst] QSocket- QDataStream

Beitrag von stonecold »

Hallo,

ich verschicke eine Struktur übers Netzwerk (Localhost). Dazu nutze ich die Klasse QDataStream. Es scheint eigentlich auch gut zu funktionieren.

Hier mal die wichtigsten Codeteile.
Client:

Code: Alles auswählen

void client::sendToServer()
{
	myStruct ms;
	ms.lat = 88.89;
	
	char data[sizeof(myStruct )];
	memcpy(data, &ms, sizeof(myStruct ));
	
	QDataStream dataStream(socket);
	dataStream.setVersion(6);

        dataStream.writeRawBytes( data, sizeof(myStruct ) );
        std::cout << "client::sendToServer(): " << std:: endl;
} 
Server:

Code: Alles auswählen

void server::incomingDataSlot()
{
	QSocket* nsocket =(QSocket*)sender();
	QDataStream dataStream( nsocket );
	dataStream.setVersion(6);
	
	myStruct ms;
	char data[sizeof(myStruct)];
	
	dataStream.readRawBytes( data, sizeof(myStruct) );
	
	memcpy(&ms, data, sizeof(myStruct));
	std::cout << "ms.lat = " << ms.lat << std::endl;	
}
Nun die Frage. Ist mit der derzeitigen Umsetzung garantiert, dass die Daten immer vollständig beim Server ankommen auch wenn mehrere Pakete verschickt werden?
Wenn nicht, wie kann ich das am besten umsetzen?

Mal zum Verständnis, wo genau werden die Daten in Pakete geteilt, verschickt und wieder zusammengebaut? Muss ich mich da überhaupt drum kümmern?
Zuletzt geändert von stonecold am 12. Dezember 2007 07:23, insgesamt 1-mal geändert.
stonecold
Beiträge: 147
Registriert: 19. Oktober 2005 10:48

Beitrag von stonecold »

Clientseitig scheinen die zu übertragenden Daten in mehrere Pakete aufgeteilt zu werden. Kann ich das verhindern? Wenn nicht woher weiß ich dann welche Pakete wie zusammen gehören?
stonecold
Beiträge: 147
Registriert: 19. Oktober 2005 10:48

Beitrag von stonecold »

Okay, habe jetzt selbst ne Lösung gefunden.

Code: Alles auswählen

while(socket->bytesAvailable() != sizeof(data))
{
	socket->waitForMore(10);
}
socket->readBlock( data, sizeof(data) );
Muss natürlich noch in Richtung Timeout verbessert werden.....
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Daten erst in ein QByteArray speichern und wenn genug Daten da -> konvertieren.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
stonecold
Beiträge: 147
Registriert: 19. Oktober 2005 10:48

Beitrag von stonecold »

Hallo Christian,

ich habe gerade ein Problem und dein Hinweis

>>> Daten erst in ein QByteArray speichern und wenn genug Daten da -> konvertieren.

könnte die Lösung sein. Verstehe ich das richtig?
Die eingehenden Daten werden im Array gespeichert anschl. frage ich die Größe ab. Ist die Arraygröße dann >= der Erwartenden Nachricht kopiere ich die Daten aus den Array raus und lösche sie dann in dem Array (FIFO)?
Warum kommen die Pakete nicht komplett an, also warum wird der incomming-Slot nicht erst dann aufgerufen wenn die Daten komplette da sind? Der Server weiß doch wie groß sie sein müssen? Kann ich mich darauf verlassen, dass die Pakete in der richtigen Reihenfolge kommen?

Leider werde ich aus der Doku nicht richtig schlau. Weißt du wo ich ggf. ein Beispiel finde?

Danke und Gruß
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Sie kommen immer in der richtigen Reihenfolge an - sonst würde TCP irgendwie nicht korrekt funktionieren. Die Daten werden aber in Stücke zu xx byte zerteilt (netzwerk-Grundwissen) - deshalb kommt ein 'bytesReceived()' immer an wenn Daten vorhanden sind. Deine Netzwerkkarte weiss ja nichts von deiner Datenstruktur.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
stonecold
Beiträge: 147
Registriert: 19. Oktober 2005 10:48

Beitrag von stonecold »

Okay danke. Soweit war es mir eigentlich klar. Ich gehe mal davon aus, dass wenn Daten kommen, die noch nicht die richtige Reihenfolge weil beispielsweise noch ein Paket fehlt der Aufruf auch nicht erfolgt?!

Bleibt noch mein QByteArray-Problem.
stonecold
Beiträge: 147
Registriert: 19. Oktober 2005 10:48

Beitrag von stonecold »

Hallo Christian,

ich versuche gerade die empfangenen Daten in ein QByteArray zu schreiben und erst wenn genug Daten diese dann weiter zu leiten.
Es geht auch anders deshalb mal meine erste Frage:
Warum die Daten im Array zwischenspeichern? Ich will das nicht einfach machen ohne genau zu wissen warum.

Möglich wäre doch auch:

Code: Alles auswählen

//...
char data[messageSize]
//...
//... incommingDataSlot
	if(socket->bytesAvailable() >= messageSize)
	{
		socket->readBlock( data, messageSize );
		emit incommingDataSignal( data, messageSize );
	} 
So dann versuche ich jetzt die Daten zu speichern, Mein Ansatz:

Code: Alles auswählen

//... incommingDataSlot
	QSocket* socket =(QSocket*)sender();	
	QDataStream dataStream( socket );
	dataStream >> *dataMemory;  // dataMemory -> QByteArray*  
	
	if( dataMemory->size() >= messageSize )
	{
		
	}
Aber wie geht's in der Schleife nun weiter?
Muss ich die Daten jetzt mittels memcpy in das char-Array speichern und die Daten aus den ByteArray löschen??? Habe irgendwie keine interessante Funktion gefunden
und finde das Vorgehen deshalb und nicht zuletzt Aufgrund meiner Unwissenheit über die Sachen mit dem ByteArray ziehmlich umständlich.

Danke und Gruß,
Mario
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Du kannst natürlich auch abfragen ob genug Daten vorhanden sind und ansonsten das event einfach ignorieren. Würde das umkopieren in das QByteArray sparen.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
stonecold
Beiträge: 147
Registriert: 19. Oktober 2005 10:48

Beitrag von stonecold »

Okay, THX!
Antworten