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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Потоковая прием/передача данных в JSON (через QTcpClient)  (Прочитано 4382 раз)
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« : Январь 10, 2012, 16:40 »

Как грамотно организовать потоковую передачу данных в формате JSON сокетами Qt? (не Http, SSL...).
Размер каждого JSON кадра порядка 30-50Кб. Данные приходят от сервера с частотой 4 раза в секунду.
Раньше передавали кадры бинарных данных (по сути слепки памяти) и размеры кадров были всегда одними и теми же.
Но такой подход очень не гибкий, решили передавать данные в тексте, в угоду универсальности передаваеммых данных.
Данные сервер будет передавать без сериализации QDataStream (так как пишется не на Qt,а на boost).
Записан
asvil
Гость
« Ответ #1 : Январь 10, 2012, 16:52 »

парсить json, не?
Записан
fuCtor
Гость
« Ответ #2 : Январь 10, 2012, 16:54 »

Посмотри на это решение:
http://qjson.sourceforge.net/
Умеет цепляться к QIODevice, но как себя будет вести на потоковых устройствах не знаю. Есть еще момент с разделением пакетов, тоже придется как-то решить, либо дожидаться прихода пакета целиком (по доп заголовку) и после уже разбирать.
Записан
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #3 : Январь 10, 2012, 17:42 »

вот мой код (еще не опробован, так как сервер не готов)
Код:
void     QGenericArmClient::readyRead()
{
    int bytesAvail = fsocket->bytesAvailable();

#ifdef  JSON_FORMAT
    if(bytesAvail<=0) return;
    QByteArray  packetData = fsocket->readAll();

    if(!packetData.isEmpty())
    {
        int terminatorIndex;
        int prevTerminatorIndex = 0;
        int dataSize = packetData.size();

        terminatorIndex = packetData.indexOf('\0',prevTerminatorIndex); //ищем первый терминатор в пакете
        if(terminatorIndex<0)   //если нет терминатора, копируем целиком
        {
            fcurrentData.append(packetData);
        }
        else
        {
            do  //проходимся по кадру
            {
                fcurrentData.append(packetData.mid(prevTerminatorIndex,(terminatorIndex-prevTerminatorIndex))); //копируем часть до терминатора
                emit jsonFrameReceived(QString(fcurrentData));  //сигналим об очередной строке с json
                fcurrentData.clear();                           //стираем временный буфер
                prevTerminatorIndex = terminatorIndex+1;        //сдвигаем указатель, с которого будем искать следующий терминатор
            }
            while(((terminatorIndex = packetData.indexOf('\0',prevTerminatorIndex))<0) || (prevTerminatorIndex>dataSize));  //до тех пор, пока больше нет терминаторов
            if(prevTerminatorIndex<dataSize)
            {
                fcurrentData.append(packetData.mid(prevTerminatorIndex,(dataSize-prevTerminatorIndex)));//копируем остаток
            }
        }
    }
#endif
}

планируется гонять текст json,завершающийся нулём (признак окончания пакета).
« Последнее редактирование: Январь 10, 2012, 17:44 от Fregloin » Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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