Empfangene QTcpSocket Daten in eignes Union speichern

Alles rund um die Programmierung mit Qt
Antworten
rubikon
Beiträge: 89
Registriert: 27. Mai 2010 13:23

Empfangene QTcpSocket Daten in eignes Union speichern

Beitrag von rubikon »

Moin.

Meine Anwendung empfängt über einen QTcpSocket Daten. Diese möchte ich in ein struct bzw. union speichern welches vereinfacht etwas so aussieht:

Code: Alles auswählen

typedef struct
{
        int		Length;
        int		Type;
        union
        {
            MyText     Texts;
            MyData     Data;
            MyXYZ      XYZ;
        };
} MyComDef;
Der readyRead() Slot sieht bei mir so aus:

Code: Alles auswählen

void QSocketEngine::ReadFromSocket()
{
    QByteArray ByteArray;

    ByteArray = m_pTcpSocket->readAll();

    memcpy(&m_MyCom, ByteArray.data(), ByteArray.count());
}
Das scheint soweit auch zu funktionieren. Da ich aber noch sehr frisch in Qt bin, würde ich gerne mal einige Meinungen hören ob das so der beste/eleganteste Weg ist, oder ob man das besser lösen könnte.

Was mich an der Lösung schon mal stört ist, dass ich die Funktion memcpy verwende und somit windows.h einbinden muss.

Muss ich sonst irgendetwas in der Socket-'Empfangsroutine' beachten? Gibt es noch irgendwelche Stolperfallen?

Vielen Dank.

Edit: Schreibfehler korrigiert
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Beitrag von RHBaum »

Jegliche TypÜberpruefung schickst du damit über den Jordan, wirst du aber eh nicht umgehen koennen.
Sprich die Konsistenz deiner Daten muss deine ProgrammLogic selber überwachen. Aber denk dessen bist Dir eh selber bewusst.

Problem bei deinem Ansatz ist, wenn Du viel und oft Daten schickst, ist nicht garantiert dass du die daten in gleichen Happen wieder rauskriegst.

D.H. im Ernstfall:
nehmen wir an deine Structgroesse ist 4+4+20 Byte = 28 byte.
(Ich hoffe deine MyText Dinger sind statische Typen , also sowas wie char [20] und keine üblichen zeichenketten ? )

du schickst 3 mal deine daten ab, also 3x28
das heisst, das auf der anderen seite 3x28 rauskommen ist hoechstwahrscheinlich, aber nicht garantiert .....

TCP garantiert Dir nur, das alle daten in reihe kommen und das keine vorlorengehen. wie es die dinger aufsplittet, ist implementierungsspezifisch.

das heisst du solltest dir deine Daten besser direkt vom socket geben lassen mit pTcpSocket.read(&m_MyCom,sizeof(MyComDef)); das bloeckiert so lange bis es die angenommen 28byte hat oder mehr, und du musst gleich wieder auf das read gehen, bis irgendwann mal ne abbruchbedingung kommt (die selber definieren musst) oder nen timeout.

Übrigens
typedef struct { .... ist C
bei c++ solltest das Typedef weglassen.

Und besser waeren Klassen die sich selber serianlisieren koennen.
Also Daten verpacken als

Code: Alles auswählen

class  MyComDef
{
public: 

private: 
        int      Length;
        int      Type;
        union
        {
            MyText     Texts;
            MyData     Data;
            MyXYZ      XYZ;
        };
}; 
und dann nen Operator >> fuer QDataStream schreiben .

dann wuerde das so aussehen :

Code: Alles auswählen

QDataStream streamIn(m_pTcpSocket);
while ( /// Abbreuch Bedingung formulieren bspWeise m_MyCom != CCancelCom wobei CCancelCom ein definiertes Object ist was den abbruch bestimmt, und != und == fuer die MyComDef's ueberladen sind ) 
{
     streamIn >> m_MyCom; 
     /// irgendwas mit m_MyCom machen 
}
Übrigens dreht Dir QDataStream die bytes noch in die in TCP spezifizierte reihenfolge, so das der wert den als int in einen socket reinschiebst, auch als numerisch der selbe wert rauskommt. Unabhanegig ob beide systeme gleiche Byteausrichtung haben, oder eines Little Endian und das andere BigEndian ist.

Ciao ...
Antworten