Форум программистов, компьютерный форум, киберфорум
C++ Qt
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.75/40: Рейтинг темы: голосов - 40, средняя оценка - 4.75
0 / 0 / 0
Регистрация: 30.09.2017
Сообщений: 182

Недопонимание QByteArray

10.01.2018, 11:14. Показов 9093. Ответов 47

Студворк — интернет-сервис помощи студентам
У меня происходит соединение по UDP, всё происходит на моём компьютере. Есть программа, которая отправляет строчки раз в секунду

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
UdpServer::UdpServer(QWidget* pwgt /*=0*/) : QTextEdit(pwgt)
{
    setWindowTitle("UdpServer");
 
    m_pudp = new QUdpSocket(this);
 
    QTimer* ptimer = new QTimer(this);
    ptimer->setInterval(1000);
    ptimer->start();
    connect(ptimer, SIGNAL(timeout()), SLOT(slotSendDatagram()));
}
 
// ----------------------------------------------------------------------
void UdpServer::slotSendDatagram()
{
    QByteArray baDatagram;
    QDataStream out(&baDatagram, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_5_7);
    QString string = "some amazing things";
    append("Sent:" + string);
    out << string;
    m_pudp->writeDatagram(baDatagram, QHostAddress::LocalHost, 1234);
}
На приёмнике происходит следующее

C++ (Qt)
1
2
3
4
socket = new QUdpSocket(this);
 
        socket->bind(1234);
     connect(socket, SIGNAL(readyRead()), SLOT(read()));
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void MainWidget::read()
{
 
 
 
    QByteArray baDatagram;
 
    if (socket->hasPendingDatagrams())
    {
 
        QHostAddress *address = new QHostAddress;
 
        baDatagram.resize(socket->pendingDatagramSize());
        socket->readDatagram(baDatagram.data(), baDatagram.size(), address);
        qDebug() << baDatagram;
.........
}
и вот тут у меня череда вопросов, которые могут показаться вам дуратскими, но с которыми я не могу разобраться
почему в дебаге получается вот такое
\x00\x00\x00&\x00s\x00o\x00m\x00""e\x00 \x00""a\x00m\x00""a\x00z\x00i\x00n\x00g\ x00 \x00t\x00h\x00i\x00n\x00g\x00s

в какой форме вообще он выводит этот Байт Аррей? Я думал, что х будет означать Hex форму, но ничего подобного
я вижу здесь свои буквы, но к чему, например \x00 (при qDebug() << baDatagram.toHex() он дописывает дополнительные 00 перед каждой буквой, почему он это делает????)
Откуда иногда берутся вот эти кавычки ""
Почему перед строкой помимо всего прочего он дописывает это "\x00\x00\x00&"

Заранее спасибо.
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
10.01.2018, 11:14
Ответы с готовыми решениями:

QByteArray
Добрый день! Каким образом проще считать из файла с 5 по 10 байт? Два последних байта считываю так: QString...

QByteArray и UCS2-BE
Есть юникод строки в виде hex QString(&quot;042304320430043604300435043C044B04390020041A&quot;); насколько я понял это в UCS-2BE кодировке. ...

QByteArray в int
Привет всем! Ситуация такая: с контроллера через COM передаю unsigned long int ловлю в Qt QByteArray так: QByteArray byte; ...

47
4 / 4 / 0
Регистрация: 12.11.2018
Сообщений: 511
22.08.2020, 10:47
Студворк — интернет-сервис помощи студентам
ValeryS, Вроде (|) так не работало, либо я не помню уже в чем была проблема, но в любом случае подсказали другую запись, вроде все нормально работает
C++ (Qt)
1
DataRes1 = static_cast<quint8> (Data[0])*0x100+static_cast<quint8> (Data[1]);
0
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,875
22.08.2020, 11:36
Цитата Сообщение от DmitryDDDD Посмотреть сообщение
но в любом случае подсказали другую запись,
поменяй в ней + на | и получишь тот же результат
Цитата Сообщение от DmitryDDDD Посмотреть сообщение
Вроде (|) так не работало,
позвольте не поверить
вот два байта 0xAA 0xBB
после сдвига на 8 получаем 0xAA00
тоже получаем при умножении на 0x100
теперь прибавляем 0xBB и получаем 0xAA00+0xBB=0xAABB
а с операцией "ИЛИ" - 0xAA00 | 0xBB=0xAABB
то же самое
0
4 / 4 / 0
Регистрация: 12.11.2018
Сообщений: 511
22.08.2020, 12:20
ValeryS, возможно, спорить не буду, не помню в чем была проблема)
0
4 / 4 / 0
Регистрация: 12.11.2018
Сообщений: 511
06.09.2020, 12:16
insite2012, Здравствуйте, сейчас изучаю книгу Макса Шлее, возник вопрос относительно потоков. Есть ли смысл при инициализации соединения создавать отдельный поток для работы сокета, в котором будет осуществляться прием данных, и их запись в буфер, а дальше передавать симафор основному потоку программы, который будет обрабатывать эти данные?
На всякий случай напоминаю логику работы связки МК - ПК:
Цитата Сообщение от DmitryDDDD Посмотреть сообщение
На МК настроено несколько каналов 12 битного АЦП (для отладки я пока взял только 1 канал). АЦП несколько раз в секунду измеряет состояние входов, DMA извлекает данные. Дальше в зависимости от входящего сигнала с ПК на МК, данные АЦП усредняются (в 10, в 100 или в 600 раз), Еще из входящих сигналов для МК это запуск передачи данных и их остановка.
Итого для МК входящие сигналы: запуск АЦП, остановка, значение во сколько раз усреднять данные. Сигналы могут быть посланы от пользователя в процессе работы МК.
Теперь что делает программа на ПК: создает файл (csv) единоразово, при запуске. Дальше по приходу данных от МК они преобразуются сначала в 16-битные, затем сравниваются с массивом значений (здесь происходит подмена принятых данных значением из массива, т.к. принимаем мы величину АЦП, а затем меняем ее на идентичную ей величину температуры), и записываются в csv файл в виде строки первым аргументом которой идет время приема обработанной партии данных. Как-то так
0
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
06.09.2020, 17:37
Цитата Сообщение от DmitryDDDD Посмотреть сообщение
возник вопрос относительно потоков
Если у вас только один мк с которым проводится работа, то на мой взгляд имеет смысл сделать два потока-один основной (интерфейса) и один вторичный, в котором и будет осуществляться работа с сокетом. Но это не обязательно, многое зависит от требований и логики работы с сокетом, он сам по себе асинхронный, и можно и из основного потока записать в него данные, а потом просто ждать получения ответа.
Я делал приложение работающее с разновидностью сокета (QBluetoothSocket), мне приходилось выносить логику работы с ним в отдельный поток, поскольку после посылки запроса мне нужно было дождаться ответа, т.к. каждый последующий запрос основан на том, что я получаю. И чтобы не замораживать интерфейс, я выносил все в отдельный поток.
0
4 / 4 / 0
Регистрация: 12.11.2018
Сообщений: 511
08.09.2020, 12:17
insite2012, ну вот я тоже потом задумался о том, что сокет асинхронный, решил оставить все в одном потоке, программа не сильно загружена действиями. Столкнулся с такой проблемой, может подскажите, как передать из одного объекта данные в функцию, например по нажатию кнопки передать стоку из LineEdit:
Функция, которая обрабатывает значение в LineEdit по нажатию кнопки:
C++ (Qt)
1
2
3
4
5
void MainWindow::on_SendLine_Button_clicked()
{
    DataSendLineEdit = ui->SendData_lineEdit->text();
    DataSend = DataSendLineEdit.toUtf8();
}
Функция отправки данных по сокету:
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
void MainWindow::slotSendToServer()
{
    //socket->write();
 
    QByteArray  arrBlock;
    QDataStream out(&arrBlock, QIODevice::WriteOnly);
    out << quint16(0) << SendData_lineEdit->text();
 
    out.device()->seek(0);
    out << quint16(arrBlock.size() - sizeof(quint16));
 
    socket->write(arrBlock);
}
Вот грубо говоря мне надо чтобы как нажали кнопку, данные из LineEdit отправились в void MainWindow::slotSendToServer() ну и соответственно дальше по сокету. Пытался связать это через сигналы и слоты, но не работает:
C++ (Qt)
1
connect(SendLine_Button, SIGNAL(clicked()), socket, SLOT(slotSendToServer()));
Такая же ситуация и когда я хочу принятые сокетом данные передать в другую функцию для обработки
0
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
08.09.2020, 13:31
Цитата Сообщение от DmitryDDDD Посмотреть сообщение
Пытался связать это через сигналы и слоты, но не работает
Не совсем понятно, к чему тут вам сигналы и слоты. Я так понимаю, у вас объект сокета в области видимости основной формы, так почему бы не сформировать блок данных и потом его отправить сокету сразу в обработчике сигнала нажатия кнопки? То же самое касается и приема, подключили слот основной формы к сигналу сокета readyRead(), в этом слоте приняли данные и вывели куда нужно.
0
4 / 4 / 0
Регистрация: 12.11.2018
Сообщений: 511
09.09.2020, 12:10
insite2012,
Цитата Сообщение от insite2012 Посмотреть сообщение
так почему бы не сформировать блок данных и потом его отправить сокету сразу в обработчике сигнала нажатия кнопки?
Ну да, сейчас у меня так и сделано, просто я думал сделать отдельный и единственный слот для отправки данных по сокету, а уже от кнопок и прочего передавать данные для отправки этому слоту, с этим у меня проблема и возникла, но можно и как вы написали, тут для моей программы особо разницы нет.
Но сейчас есть другая трудность, похожая на эту. Раньше у меня в коде в функции, которая принимала входящие данные вызывались другие функции, которые эти данные обрабатывали и работали с ними, что является ошибкой. Теперь же я хочу, что мой слот сокета slotReadyRead прочитав нужные ему 10 байт данных Data=socket->read(10); значение Data передал в другой слот или функцию уже не оскета, а основной программы, для дальнейшей обработки

Добавлено через 5 минут
Сейчас это сделано так:
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
void MainWindow::slotReadyRead()
{
    Data.clear();
    qint64 bytesAvailable1 = socket->bytesAvailable();
    qDebug() << "Bytes available1: " << bytesAvailable1;
 
    if (bytesAvailable1>=10)
    {
        Data=socket->read(10);
         // Начало обработки данных
        if(!Data.isEmpty() && Data.size()>=10)
        {
            emit signalDataAvailable(Data);
            qDebug()<<"Data:"<<Data;
 
            NumCount = static_cast<quint8> (Data[0])*0x100+static_cast<quint8> (Data[1]);
            QString NumString = QString::number(NumCount);
            ui->NumCount_label->setText(NumString);
            qDebug()<<"NumCount:"<<NumCount;
 
            DataRes1 = static_cast<quint8> (Data[2])*0x100+static_cast<quint8> (Data[3]);   // Transform 2 bytes of Data to unsigned shorts DataRes
            QString DataString1 = QString::number(DataRes1);
            ui->Data_label1->setText(DataString1);
            qDebug()<<"DataRes1:"<<DataRes1;
 
           // повторяется тоже самое для остальных байт массива
 
            qint64 bytesAvailable2 = socket->bytesAvailable();
            qDebug() << "Bytes available2: " << bytesAvailable2;
        }
        else
        {
            emit signalError(QObject::tr("No answer from mcu"));
            ui->Error_label->setText("No answer from mcu");
            qDebug()<<"strError:"<<"No answer from mcu";
        }
    }
}
slotReadyRead это слот сокета
C++ (Qt)
1
connect(socket, SIGNAL(readyRead()), this, SLOT(slotReadyRead()));
Дальше я создаю другой слот ну или функцию, уже видимо принадлежащую основному потоку программы:
C++ (Qt)
1
2
3
4
void MainWindow::slotDataTransform()
{
 
}
И вот всю обработку данных хочу перенести сюда. Данные здесь обработаются и передадутся в следующую функцию, которая уже будет обрабатывать данные дальше. Как программно можно это реализовать?

Добавлено через 9 минут
Может немного сумбурно объясняю, но там суть в том, что как только мы считали сокетом нужное количество байт, необходимо вызвать функцию обработчик данных и передать ей эти данные, дальше эта функция после обработки вызывает следующую функцию и передает ей обработанные данные

Добавлено через 4 часа 15 минут
Цитата Сообщение от DmitryDDDD Посмотреть сообщение
Дальше я создаю другой слот ну или функцию, уже видимо принадлежащую основному потоку программы:
Тут я ошибся, скорее так:
Функция обработки данных
C++ (Qt)
1
2
3
4
QVector<quint16> MainWindow::CreateTcpDataArray(const QByteArray &data)
{
 
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
09.09.2020, 12:10

Структуру в QByteArray
Как перевести произвольную структуру в QByteArray и обратно? struct MyStruct { int a; float b; QString str; };

QImage и QByteArray
Приветствую Для того, чтобы сохранить фотографию в БД, я ее из QImage перегоняю в QByteArray и далее сохраняю в Blob поле в БД Вот...

Запись в QByteArray
Здравствуйте, у меня такой вопрос. Допустим я веду счётчик: 1,2,3,4 и т.д. до 65535. В 16-ричном виде эти числа, соответственно...

QByteArray и память
Доброй ночи) Короче есть код который записывает кусок одного файла в другой qds.readRawData(buf,...

Qt C++ QByteArray QFile
Здравствуйте! Возникла проблема: имеется файл, в нем данные записываются следующим образом: первые байт - младший байт, второй байт -...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
48
Ответ Создать тему
Новые блоги и статьи
Часы электронные
Uhbif79 12.08.2026
Выкладываю программу часов. Программа позволяет: 1. Использовать системное время и дату, 2. Есть возможность вводить время и дату вручную. 3. Реализованы 2 будильника: начало и конец рабочего дня. . . .
Часы с будильником на основе класса QLCDNumber
Uhbif79 12.08.2026
Всем добрый день, выкладываю программу часов с будильником на основе класса QLCDNumber. Здесь я пробовал самостоятельно создавал классы, впервые столкнулся с видимостью переменной одного класса из. . .
Установка MinGW GCC 16.2 и CMake
8Observer8 10.08.2026
VK Видео: https:/ / vkvideo. ru/ video-240781534_456239017 YouTube: eY5-5PyI9NM Текстовая версия
Неделя из жизни имитационной модели склада: мои кривые руки растут, откуда надо
anaschu 10.08.2026
Неделя из жизни имитационной модели склада: как я почти написал неправильную логику и что с этим делать Работаю сейчас над учебно-рабочим проектом: строю в AnyLogic имитационную модель процессов. . .
Калькулятор для расчета родства
russiannick 07.08.2026
1. Задача: Создать калькулятор для расчета родства. Родственных связей существует 8 ступеней, такие как: p - отец P - мать q - муж Q - жена b - брат B - сестра s - сын S - дочь
Мир по моей воле
kumehtar 07.08.2026
Когда-то кажется, что всё просто. Ты весь такой светлый. Причиняешь добро. Борешься за справедливость в этом тёмном мире. Потом начинаешь замечать одну неприятную вещь. Почти каждый хороший. . .
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
У нас сейчас поговорку "Опять 25" нужно переделать на "Опять +35".
kumehtar 04.08.2026
С ностальгией вспоминаю времена моего детства, когда у нас и правда +25 - была максимальная температура летом. Раньше +25 °C реально казались вершиной жары, когда можно было весь день пропадать на. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru