Russian Qt Forum

Qt => Работа с сетью => Тема начата: GPPsoft от Декабря 03, 2013, 07:39



Название: QTcpSocket принимает данные не полностью.
Отправлено: GPPsoft от Декабря 03, 2013, 07:39
Здравствуйте. Читаю данные из сокета по сигналу readyRead. Но не могу понять одно, почему данные приходят не полностью. Вернее сами данные приходят, то полностью но как-то частями что ли... К примеру сервер посылает такие данные(очередность пакетов):

   1.Привет
   2.Как
       пауза в отправке данных
   3.Дела

Пока не будет отправлен пакет #3 я не увижу данных пакета 1 и 2. Пробовал устанавливать буфер setReadBufferSize но это ничего не дает. Как я понимаю тут как только приходят данные, то срабатывает сигнал readyRead? Но почему тогда происходит такая ситуация?

Код:
void MainWindow::on_data()
{
    QByteArray data=tcpSocket->readAll();
    .... Какая-то обработка данных....
}

Ранее я работал с сокетами в Java и C# и делал так и без проблем получал все порции данных сразу, даже если приходила часть отправленного пакета:
Код:
int receivedBytes;
byte[] dataBuffer = new byte[Session.BUFFER_SIZE];

InputStream stream=mTcpClient.getInputStream();

while ((receivedBytes = stream.read(dataBuffer, 0, dataBuffer.length)) != -1) {
обработка_данных(dataBuffer, receivedBytes);
}

 Как сделать подобное в QT5? Спасибо.


Название: Re: QTcpSocket принимает данные не полностью.
Отправлено: Old от Декабря 03, 2013, 08:27
В Qt данные буферизируются, хотите немедленной отправки используйте для сокета flush(). Дальше отправкой будет заниматься сетевой стек ОС, он, по умолчанию, тоже сразу ничего не отправляет.


Название: Re: QTcpSocket принимает данные не полностью.
Отправлено: GPPsoft от Декабря 03, 2013, 08:29
В Qt данные буферизируются, хотите немедленной отправки используйте для сокета flush(). Дальше отправкой будет заниматься сетевой стек ОС, он, по умолчанию, тоже сразу ничего не отправляет.

Спасибо. Кажется проблема решилась вот так:
Код:
void MainWindow::on_data()
{
    while(tcpSocket->bytesAvailable())
    {
        QByteArray data=tcpSocket->readAll();
        packetSplitter->setByteArray(&data,data.length());
    }
}
Насколько это правильно?


Название: Re: QTcpSocket принимает данные не полностью.
Отправлено: Old от Декабря 03, 2013, 08:37
Насколько это правильно?
Это также не гарантирует, что вы получите все данные.
Данные могут приходить по частям. С приходом каждой части будет срабатывать readyRead.
Вам нужно накапливать приходящие данные и контролировать самому все пришло или нет.
И только после этого начинать их обрабатывать.


Название: Re: QTcpSocket принимает данные не полностью.
Отправлено: GPPsoft от Декабря 03, 2013, 08:46
Насколько это правильно?
Это также не гарантирует, что вы получите все данные.
Данные могут приходить по частям. С приходом каждой части будет срабатывать readyRead.
Вам нужно накапливать приходящие данные и контролировать самому все пришло или нет.
И только после этого начинать их обрабатывать.
Вы имеете в виду проблему "склеивания" и прихода пакетов по частям? К примеру сначала пришло "При", а при последующем readyRead "вет"? Если да, то у меня это решено протоколом и самописным классом PacketSplitter.


Название: Re: QTcpSocket принимает данные не полностью.
Отправлено: Old от Декабря 03, 2013, 08:57
Вы имеете в виду проблему "склеивания" и прихода пакетов по частям? К примеру сначала пришло "При", а при последующем readyRead "вет"? Если да, то у меня это решено протоколом и самописным классом PacketSplitter.
Тогда все нормально.


Название: Re: QTcpSocket принимает данные не полностью.
Отправлено: GPPsoft от Декабря 03, 2013, 09:16
Вы имеете в виду проблему "склеивания" и прихода пакетов по частям? К примеру сначала пришло "При", а при последующем readyRead "вет"? Если да, то у меня это решено протоколом и самописным классом PacketSplitter.
Тогда все нормально.
Помогите если можете еще вот с этим вопросом (http://www.prog.org.ru/topic_26099_0.html).