Russian Qt Forum
Ноябрь 22, 2024, 14:20 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Проблемы с QTcpSocket->ReadAll()  (Прочитано 7843 раз)
Harlon
Гость
« : Май 28, 2018, 14:15 »

Суть проблемы: сервер передает массив int размером 8000 байт. Клиент принимает этот массив через readAll(), всё это переводится в QVector через QDataStream, дальше программа отрисовывает график из массива. Но в большинстве случаев получается следующая картина, клиент принимает сначала половину или более меньшую(большую) часть данных, начинает рисовать график, потом вектор обрывается и принимается остаток данных и вырисовывется уже крокозябра, а не график. Размер передаваемых данных статичен, т.е. всегда 8000 байт. Вопрос, как заставить дочитать все данные, от сервера? Помогите пожалуйста. Я конечно наверное всех уже задолбал со своими вопросами, но возможно эта тема поможет не только мне, спасибо за понимание.

Код
C++ (Qt)
void readSocketData()
{
   while(socket->bytesAvailable())
       datacounter += socket->readAll().length();
   qDebug() << datacounter;
}
 

Нашел пример в интернете, только не догоняю, что тут проверяется в цикле. Т.е. bytesAvailable() возвращает число прочитанных байт и если я правильно понял, то в моем случае их надо сравнить с моим размером сообщения.

Код
C++ (Qt)
int x = 8000;
while(x > socket->bytesAvailable())
       datacounter += socket->readAll().length();
 

Вот как-то так?
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #1 : Май 28, 2018, 14:31 »

Тебе надо вешаться на сигнал readyRead и в нем вычитывать все в свой буфер, а буфер проверять на размер - если 8000, то можно парсить.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Harlon
Гость
« Ответ #2 : Май 28, 2018, 15:37 »

Код
C++ (Qt)
connect(socket, SIGNAL(readyRead()),this,SLOT(sockASCANRead()));
...
 
void MainWindow::sockASCANRead()
{
   if (socket->waitForConnected(500))
   {
       int x = 8000;
       while(x > socket->bytesAvailable())
       {
           ASCANData = socket->readAll();
       }
...
}
 

Так?
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #3 : Май 28, 2018, 15:40 »

Код
C++ (Qt)
connect(socket, SIGNAL(readyRead()),this,SLOT(sockASCANRead()));
...
 
void MainWindow::sockASCANRead()
{
   for (;;) {
       const auto bav = socket->bytesAvailable();
       if (bav < 8000)
           return;
 
       const auto data = socket->read(8000);
       // do parse
   }
...
}
 
Записан

ArchLinux x86_64 / Win10 64 bit
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #4 : Май 28, 2018, 15:45 »

Код
C++ (Qt)
connect(socket, SIGNAL(readyRead()),this,SLOT(sockASCANRead()));
...
 
void MainWindow::sockASCANRead()
{
 buffer_ += socket->readAll();
 if (buffer_.size() >= 8000) {
   parse();
   buffer_.remove(0, 8000);
 }
}
 
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Harlon
Гость
« Ответ #5 : Май 28, 2018, 15:46 »

Спасибо, попробую сделать, отпишусь о результате.

ВСЁ отлично, всем спасибо!
« Последнее редактирование: Май 29, 2018, 09:06 от Harlon » Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.227 секунд. Запросов: 22.