S
S
sddvxd2018-09-09 19:44:29
Qt
sddvxd, 2018-09-09 19:44:29

Why are more bytes coming in than specified?

Hello!
I wanted to master data transfer not entirely, but blockwise. The code is a chat. As soon as the client sends a message to the server, the server broadcasts the message to a collection of client sockets. That is, the person who wrote the message will see his message only when he receives it from the server. Otherwise, I don’t know yet how to make the
Client:

void Client::slotReadyRead(){
    QDataStream in(pSocket);
    in.setVersion(QDataStream::Qt_5_3);

    for(;;){

        if(pSocket->bytesAvailable() < sizeof(quint16)){
            return;
        }
        in >> nNextBlockSize;

        if(pSocket->bytesAvailable() < nNextBlockSize){
            return;
        }
        QString str;

        in >> str;

        QString strMessage = str;
        pTextEdit->append(str);
        nNextBlockSize = 0;
    }
}

void Client::slotSendToServer(){
    QByteArray arrBlock;
    QDataStream out(&arrBlock, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_5_3);
    QHostInfo info;
    out << quint16(0) << pLineEdit->text();
    out.device()->seek(0);
    out << quint16(arrBlock.size() - sizeof(quint16));

    int nBlockSize = 4;

    int lenData = arrBlock.size();
    for(int j = 0; lenData > j && lenData >= nBlockSize; j += nBlockSize){
        pSocket->write(arrBlock, nBlockSize);
        arrBlock.remove(0, nBlockSize);
    }

    if(lenData % nBlockSize != 0){
        pSocket->write(arrBlock);
        pSocket->waitForBytesWritten();
    }
    pLineEdit->setText("");
}

Server:
void Server::sendToClients(const QString& str){

    QByteArray arrBlock;
    QDataStream out(&arrBlock, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_5_3);
    out << quint16(0) << str;
    out.device()->seek(0);
    out << quint16(arrBlock.size() - sizeof(quint16));

    int nBlockSize = 4;
    int lenData = arrBlock.size();
    QByteArray buffer(arrBlock);

    for(int i = 0; connections.count() > i; i++){
        arrBlock = buffer;
        for(int j = 0; lenData > j && lenData >= nBlockSize; j += nBlockSize){
            connections[i]->write(arrBlock, nBlockSize);
            connections[i]->waitForBytesWritten();
            arrBlock.remove(0, nBlockSize);
        }

        if(lenData % nBlockSize != 0){
            connections[i]->write(arrBlock);
            connections[i]->waitForBytesWritten();
        }
    }

}

void Server::slotReadClient(){
    QTcpSocket* pSocket = (QTcpSocket*)sender();
    QDataStream in(pSocket);
    in.setVersion(QDataStream::Qt_5_3);

    for(;;){
        if(!nNextBlockSize){
            int avail = pSocket->bytesAvailable();
            if(pSocket->bytesAvailable() < sizeof(quint16)){
                return;
            }
            in >> nNextBlockSize;
        }
        if(pSocket->bytesAvailable() < nNextBlockSize){
            return;
        }
        QString str;

        in >> str;

        QString strMessage = str;
        pTextEdit->append(strMessage);
        nNextBlockSize = 0;


        sendToClients(pSocket->peerAddress().toString() + " написал: " + str);
    }

}

The problem is that the server receives 8 bytes instead of 4. I think that each block is 4 bytes, but it still comes in 8. Half of the messages come in, half are empty lines. Please tell me what I did wrong

Answer the question

In order to leave comments, you need to log in

1 answer(s)
M
Maxim Moseychuk, 2018-09-09
@sddvxd

if(pSocket->bytesAvailable() < sizeof(quint16)){
return;
}
From here on out you read the size of the message. Then, if the number of incoming bytes is not enough, then interrupt the loop until the next piece of data.
But here's the problem. You read the size of the message again from the new portion. And there it is no longer at all, but the beginning of the message.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question