@sddvxd

Почему приходит больше байт, чем указано?

Здравствуйте!

Хотел освоить передачу данных не целиком, а блочно. Код представляет из себя чат. Как только клиент шлет сообщение на сервер, сервер рассылает это сообщение коллекции сокетов клиентов. То-есть человек, написавший сообщение, увидит свое сообщение только тогда, когда получит его с сервера. По другому пока не знаю как сделать

Клиент:

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("");
}


Сервер:

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);
    }

}


Проблема заключается в том, что сервер принимает 8 байт, вместо 4. Я думаю, что каждый блок равен 4 байт, а приходит все-равно 8. Половина сообщений приходит, половина - пустые строки. Подскажите пожалуйста, что я не так сделал
  • Вопрос задан
  • 117 просмотров
Решения вопроса 1
if(pSocket->bytesAvailable() < sizeof(quint16)){
return;
}

От этого места и дальше вы читаете размер сообщения. Затем если количество пришедших байт недостаточно, то прерываете цикл до следующей порции данных.

Но вот незадача. Вы из новой порции снова читаете размер сообщения. А там уже совсем не он лежит, а начало сообщения.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы