How to read complete data in QTcpSocket?

前端 未结 4 1555
灰色年华
灰色年华 2020-12-18 02:33

Now the server (implemented with java) will send some stream data to me, my code is like below:

connect(socket, SIGNAL(readyRead()), this, SLOT(read_from_ser         


        
相关标签:
4条回答
  • 2020-12-18 03:05

    Problem is that during tcp data transfer data are send in undefined chunks. If you are trying to read defined block size you have to know in advance expected chunk size ore have a way to determinate when your block ends (something like zero terminated c-string).

    Check if this answer doesn't help you (there is a trick to wait for expected data block).

    0 讨论(0)
  • 2020-12-18 03:09

    What you're seeing is normal for client-server communication. Data is sent in packets and the readyRead signal is informing your program that there is data available, but has no concept of what or how much data there is, so you have to handle this.

    To read the data correctly, you will need a buffer, as mentioned by @ratchetfreak, to append the bytes as they're read from the stream. It is important that you know the format of the data being sent, in order to know when you have a complete message. I have previously used at least two methods to do this: -

    1) Ensure that sent messages begin with the size, in bytes, of the message being sent. On receiving data, you start by reading the size and keep appending to your buffer until it totals the size to expect.

    2) Send all data in a known format, such as JSON or XML, which can be checked for the end of the message. For example, in the case of JSON, all packets will begin with an opening brace '{' and end with a closing brace '}', so you could count braces and match up the data, or use QJsonDocument::fromRawData to verify that the data is complete.

    Having used both of these methods, I recommend using the first; include the size of a message that is being sent.

    0 讨论(0)
  • 2020-12-18 03:12

    If all of the data has not yet arrived then your while loop will exit prematurely. You need to use a message format that will let the receiving code determine when the complete message has been received. For example, the message could begin with a length element, or if you are dealing with text the message could end with some character used as a terminator.

    0 讨论(0)
  • 2020-12-18 03:20

    you can use a buffer field to hold the unfinished data temporarily and handle packets as they complete:

    {
        while (socket->bytesAvailable())
        {
            buffer.append(socket->readAll());
            int packetSize = getPacketSize(buffer);
            while(packetSize>0)
            {
                handlePacket(buffer.left(packetSize);
                buffer.remove(0,packetSize);
                packetSize = getPacketSize(buffer);
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题