I have a problem of abnormal message when using qt socket



  • Hi, I'm using qtsocket to write a client-server project. I have a client to send message and a server to process those message. But when the processing time is long, the messages that the server receives become abnormal and I can't read normal data sometimes.

    The phenomenon is that I get normal message and intermittently some abnormal message. The abnormal message does not affect the following message. When I reduce the processing time, all the message becomes normal. Here is some of my code:

    Client

    QByteData message;
    QDataStream out(&message, QIODevice::WriteOnly);
    out<< Some Data
    socket->write(message);
    socket->flush();
    

    Server:

    //These codes are in ReadData() function
    QDataStream in(socket);
    if( block_size==0 ){
        if( socket->bytesAvailable() < (int)sizeof(quint16) )
             return;
        in>>block0_size;
    }
    if( socket->bytesAvailable() < block_size ){
        return;
    }
    in>> Read message
    Call processing function
    block_size = 0;
    

    I guess the problem is that when processing function runs for a long time, there are a lot of messages coming and buffer isn't large enough. But I don't know how to verify this hypothesis and neither how to fix it.


  • Lifetime Qt Champion

    Hi,

    What is a normal and an abnormal message for you ?


  • Qt Champions 2017

    @Charles-Zhang

    In principle there are three places where the error can be:

    1. in the client code
    2. in the server code
    3. somewhere in between (O/S or Qt)

    3 will be very unlikely. and buffer overrun even more, as Qt uses unlimited buffers by default.

    So I'd run Wireshark to see if the data looks as expected "on the wire". that should give you an hint where to investigate further - client or server side.

    Happy New Year!



  • @SGaist I use a self-defined protocol, which contains message length, message type and some data and they are normal message. The message type of abnormal message is right, but the message type become messy and so does data.



  • if( block_size==0 ) vs in>>block0_size;

    I guess it's just a typo. 2 notes:

    • since Qt 5.7 you don't need that block_size magic any more and you can just use QDataStream::startTransaction/QDataStream::commitTransaction. See the Client::readFortune() method of the fortune example
    • you need to show us what's going on in out<< Some Data and in>> Read message (the former is my prime suspect)


  • @VRonin I'm sorry, it's a typo error. I use Qt 5.2.1 so I can't use QDataStream::startTransaction.

    My message is the position and lidar data of a smart car and let me show the details.
    Client:

    QByteArray message;
    QDataStream out(&message, QIODevice::WriteOnly);
    out<<(quint16)0;
    out<<message_type; // message_type means the type of this message, for this lidar data message it is a fixed number
    long long timestamp=lidarData->timestamp;
    out<<timestamp; //Timestamp of this message
    out<<self_num; //It's the car number
    int size = lidarData->datasize; // The size of lidar data array
    out<<size;
    out<<x<<y<<ori;
    for( int i=0; i<size; i++ )
        out<<lidarData->data[i]; // lidar data
    out.device()->seek(0);
    out << (quint16)(message.size() - sizeof(quint16)); //The length of this message
    socket_host->write(message);
    socket_host->flush();
    

    Server:

    //Receive message
        QDataStream in(socket);
        if( block_size==0 ){
            if( socket->bytesAvailable() < (int)sizeof(quint16) )
                return;
            in>>block_size;
        }
        if( socket->bytesAvailable() < block_size ){
            return;
        }
    //Allocate local data
        short data[361]; //This 361 equals lidarData->datasize, which is lidar data size
        long long timestamp;
        quint32 from_num;
        int size;
        float x, y, orien;
        quint32 message_type;
    //Read message
        in>>message_type;
        if( message_type==1 ){ //if message_type is lidar data message
            in>>timestamp>>from_num>>size>>x>>y>>orien;
            for( int i=0; i<size; i++ ){
                in>>data[i];
            }
            qDebug()<<"Receive message from "<<from_num<<" message type "<<message_type<<",timestamp "<<timestamp
                   <<", message size is "<<block0_size<<", x "<<x<<", y "<<y<<", ori "<<orien
                   <<" data size "<<size<<" bytesAvailable "<<socket0->bytesAvailable();
            UpdateMap(x, y, orien, size, from_num, data);
        }
        else{
            qDebug()<<"Message type not 1";
        }
    

    The problem is about UpdateMap() function. If the process time of that function is short, all the message can be safely received. But if the time is long, the message_type of some message changes, it is not 1 and it becomes a huge negative number. All the data following the message_type becomes huge messy number.



    • Given the problem it would be nice if you can add a comment specifying the type of every variable
    • short and long long are not size safe. use qint16 and qint64 instead.
    • data[361] and in>>data[i]; is, in general, unsafe you might go out of bounds
    • if you receive anything that is not message_type==1 you keep in the buffer all the rest
    • Where are these slots called from? are you using multiple threads?

Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.