Question

I'm reading datas from socket and putting received datas from datagram to HostMessage. but when i try to show HostMessage->MessageHeader, it shows invalid data. also datagram output looks like a little different according to wireshark output.

I fixed this problem by ntonl function (and applied on MessageHeader, not all of datagram!!), b is correct result. with this solution, I have to apply ntonl to all of struct members, and I have members over 100.

Do you have any solution or idea for fix this?

Code:

unsigned int ntonl(unsigned int a){
    unsigned int b;
    char* pA = (char*)&a;
    char* pB = (char*)&b;

    for (int i = 0; i < sizeof(pA); i++){
        pB[i] = pA[(sizeof(pA)-1) - i];
    }

    return b;
}

void myDevice::processPendingDatagrams(){
    while (m_udpSocket->hasPendingDatagrams()){
    QByteArray datagram;
            datagram.resize(m_udpSocket->pendingDatagramSize());

            QHostAddress sender;
            quint16 senderPort;

            qint64 dataReceivedLength = m_udpSocket->readDatagram(datagram.data(),
                                                                  datagram.size(),
                                                                  &sender,
                                                                  &senderPort);

    tagHostMessage* HostMessage = (tagHostMessage*)datagram.data();

    qDebug("datagram: %x-%x-%x-%x", datagram.data()[0], datagram.data()[1], datagram.data()[2], datagram.data()[3]);
    qDebug()<<"msg header: " << HostMessage->MessageHeader[0] << "=" << HostMessage->MessageHeader;

    b = ntonl(HostMessage->MessageHeader[0])
}

my struct:

typedef struct tagHostMessage{
    unsigned int        MessageHeader[4];
    TMessageData MessageData;
    short int    CheckSum;

}THostMessage,*PHostMessage;

Wireshark output (1024byte):

0d:cc:97:e0:00:00:00:00:00:00:00:00:00:....

qDebug outputs:

datagram: d-ffffffcc-ffffff97-ffffffe0

msg header:  3768044557 = 0x9be9b8 

a = e097cc0d    
b = 0dcc97e0 
Was it helpful?

Solution

It seems that you're experiencing byte order problem. Since QUdpSocket inherits QIODevice, you can use QDataStream on it, and this class supports byte order conversion. Specify the byte order of incoming data:

QDataStream stream(m_udpSocket);
stream.setByteOrder(QDataStream::BigEndian); // or LittleEndian

And then you can receive data like that:

unsigned int b;
stream >> b;

Also qToBigEndian, qToLittleEndian, qFromBigEndian, qFromLittleEndian functions may be useful.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top