0 / 0 / 0
Регистрация: 30.09.2017
Сообщений: 182
1

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

10.01.2018, 11:14. Показов 6183. Ответов 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)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
10.01.2018, 11:14
Ответы с готовыми решениями:

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

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

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

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

47
7167 / 6142 / 2802
Регистрация: 14.04.2014
Сообщений: 26,462
10.01.2018, 12:01 2
Ну а что ты ожидал? Надо так же QDataStream использовать на второй стороне, только для чтения.
0
0 / 0 / 0
Регистрация: 30.09.2017
Сообщений: 182
10.01.2018, 12:06  [ТС] 3
Сначала сделать так:
C++ (Qt)
1
2
 baDatagram.resize(socket->pendingDatagramSize());
        socket->readDatagram(baDatagram.data(), baDatagram.size(), address);
а потом использовать QDataStream и считать из baDatagram в строку?
0
7167 / 6142 / 2802
Регистрация: 14.04.2014
Сообщений: 26,462
10.01.2018, 13:12 4
Второе - да. А как ты будешь определять, что получено всё, к отображению не относится.
0
0 / 0 / 0
Регистрация: 30.09.2017
Сообщений: 182
10.01.2018, 15:18  [ТС] 5
Хорошо, спасибо, ту понял, тогда другой вопрос.

Есть QByteArray.
Есть какая-то строчка, пусть будет "some amazing things"
И к ней, допустим, дописаны два байта в начало. 0х1A и 0x1B.
Надо обрабатывать только данные, которые обладают вот этой вот припиской.

Суть вопроса: как обратиться к определённому байту QByteArray правильно?
Делаю так
baDatagram[0] - выводит нужное значение, но абсолютно не понимаю, как это сравнивать с 16-ричным значением и как вообще с этим работать, потому что на все операции типа:
C++ (Qt)
1
baDatagram[0].toHex()
кьют ругается

как надо делать? как добиться того, что мне нужно: сравнивать с 16-ричными значениями первые два байта
0
Эксперт С++
8382 / 6144 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
10.01.2018, 15:37 6
C++ (Qt)
1
2
3
4
if(baDatagram.size()>=2 && baDatagram[0]== 0х1A && baDatagram[1]== 0х1B)
{
   //...
}
0
0 / 0 / 0
Регистрация: 30.09.2017
Сообщений: 182
10.01.2018, 15:49  [ТС] 7
Вот пример простой, чтобы было понятно, что у меня не получается.


C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <QCoreApplication>
#include <QDebug>
 
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
 
 
    QByteArray byte("text");
 
   if( byte[0] == 0x74)
      qDebug() << "Y";
    else qDebug() << "N";
 
 
 
    return a.exec();
}
Выдаёт такую ошибку: qbyteref::operator ==: 2 overloads have similar conversions

Я так понимаю, он не знает, использовать ли обычный оператор сравнения или какой-то перегруженный (или неправильно понимаю??).

В любом случае, в чём проблема и что с ней делать?
0
Эксперт С++
8382 / 6144 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
10.01.2018, 15:54 8
C++ (Qt)
1
if( byte[0] == QChar(0x74))
0
0 / 0 / 0
Регистрация: 30.09.2017
Сообщений: 182
10.01.2018, 16:22  [ТС] 9
Это работает для всего QByteArray
если делать
C++ (Qt)
1
if (byte == QChar(0x74))
то всё прекрасно, но это и раньше я знал

а вопрос как раз в том, чтобы анализировать именно побайтово

Предложенный Вами варианит выдаёт ошибку: binary '==': no operator found which takes a left-hand operand of type 'QByteRef' (or there is no acceptable conversion)
0
зомбяк
1564 / 1213 / 345
Регистрация: 14.05.2017
Сообщений: 3,935
10.01.2018, 16:51 10
Лучший ответ Сообщение было отмечено Koptina как решение

Решение

Вот так сработает
C++
1
2
3
4
   const char val = byte[0];
   if( val == 0x74)
      qDebug() << "Y";
    else qDebug() << "N";
Добавлено через 4 минуты
Или так:
C++
1
if( (char)byte[0] == 0x74)
Добавлено через 2 минуты
Или можно вот так:
C++
1
if( 0x74 == byte[0])
1
0 / 0 / 0
Регистрация: 30.09.2017
Сообщений: 182
10.01.2018, 16:52  [ТС] 11
Да, работает, большое человеческое спасибо)
0
3 / 3 / 0
Регистрация: 12.11.2018
Сообщений: 511
19.08.2020, 15:56 12
Avazart, nmcf, можете подсказать по QByteArray?
Аналогичный вопрос как у автора, тоже поставил меня в тупик.
По TCP принимаю данные (отправляющая сторона отправляет массив (0F, FF) это разбитое число 4095 на два байта), сответственно ожидаю принять так же массив 0F, FF. Собственно принимающей сторой я хочу собрать обратно эти 0F, FF в число 4095.

C++ (Qt)
1
2
3
4
5
6
7
uint16_t DataRes = 0;
if (socket->waitForConnected(500))
    {
        socket->waitForReadyRead(500);
        Data = socket->readAll();
        DataRes = ((Data[0]<<8)||(Data[1]));
    }
Data является QByteArray. По сути пытаюсь просто обраться к 0 и 2 ячейкам массива и записать их в uint16_t (хотя DataRes почему-то определяется как unsigned short), но я никак не могу получить корректный результат, в чем может быть проблема?
0
Эксперт С++
8382 / 6144 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
19.08.2020, 16:10 13
Цитата Сообщение от DmitryDDDD Посмотреть сообщение
По сути пытаюсь просто обраться к 0 и 2 ячейкам массива
Что бы обратиться нужно сначала проверить пришли ли эти три байта или нет.
1
2427 / 1169 / 433
Регистрация: 08.11.2016
Сообщений: 3,242
19.08.2020, 16:11 14
C++ (Qt)
1
2
3
DataRes = Data[0];
DataRes <<= 8;
DataRes += Data[1];
1
Эксперт С++
8382 / 6144 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
19.08.2020, 16:11 15
И как я помню в QByteArray вроде как char, а не uint16_t или unsigned short
1
3 / 3 / 0
Регистрация: 12.11.2018
Сообщений: 511
19.08.2020, 18:02 16
Avazart,
Цитата Сообщение от Avazart Посмотреть сообщение
Что бы обратиться нужно сначала проверить пришли ли эти три байта или нет
Вы правы, проверки наличия в QByteArray необходимых данных нету, можете подсказать как ее организовать? Там ожидается два байта информации.
Цитата Сообщение от Avazart Посмотреть сообщение
И как я помню в QByteArray вроде как char, а не uint16_t или unsigned short
QByteArray вроде char, unsigned short почему-то становится переменная, которую я объявляю как uint16_t.
Annemesski,
Цитата Сообщение от Annemesski Посмотреть сообщение
DataRes = Data[0];
DataRes <<= 8;
DataRes += Data[1];
Спасибо за код, пока проверить возможности нету, но скоро смогу
0
Эксперт .NET
5448 / 4222 / 1207
Регистрация: 12.10.2013
Сообщений: 12,208
Записей в блоге: 2
19.08.2020, 18:21 17
Цитата Сообщение от DmitryDDDD Посмотреть сообщение
наличия в QByteArray необходимых данных нету, можете подсказать как ее организовать?
Использовать сигнал readyRead() сокета, соединить его со слотом и в нем считывать информацию.
1
Эксперт С++
8382 / 6144 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
19.08.2020, 18:39 18
Проверять QByteArray::size() или как сказали в слоте через bytesAvailable()
1
3 / 3 / 0
Регистрация: 12.11.2018
Сообщений: 511
20.08.2020, 06:20 19
Annemesski, insite2012, почему-то результат преобразования отличается от ожидаемого.
Цитата Сообщение от Annemesski Посмотреть сообщение
DataRes = Data[0];
DataRes <<= 8;
DataRes += Data[1];
Вот код того, что отправляется:
C
1
2
3
4
            uint16_t adcTCPdata2 = 4095;
            adcTCPbuffer[0] = (adcTCPdata2 >> 8);
            adcTCPbuffer[1] = (adcTCPdata2);
            netconn_write(conn, adcTCPbuffer, 2, NETCONN_COPY);
Вот принимаю:
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    if (socket->waitForConnected(500))
    {        
        socket->waitForReadyRead(500);
        Data = socket->readAll();                             
 
        DataRes = Data[0];
        DataRes <<= 8;
        DataRes += Data[1];
 
        ui->Data_label->setText(Data);              
        qDebug()<<Data;
        qDebug()<<"DataRes:"<<DataRes;
        qDebug()<<"Data1:"<<Data[0];
        qDebug()<<"Data2:"<<Data[1];
    }
Вот что выводится в qDebug:
"\x0F\xFF"
DataRes: 3839
Data1: 
Data2: y
Т.е. вместо 4095 (0FFF) получаем 3839 (0EFF)

Добавлено через 21 минуту
Annemesski, insite2012, Такое преобразование помогло решить проблему
C++ (Qt)
1
2
3
        DataRes = (unsigned char)Data[0];
        DataRes <<= 8;
        DataRes += (unsigned char)Data[1];
Так правильно делать?
0
Эксперт .NET
5448 / 4222 / 1207
Регистрация: 12.10.2013
Сообщений: 12,208
Записей в блоге: 2
20.08.2020, 06:42 20
Цитата Сообщение от DmitryDDDD Посмотреть сообщение
Так правильно делать?
Я бы использовал static_cast<>, а не С-подобное преобразование типов.
1
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
20.08.2020, 06:42
Помогаю со студенческими работами здесь

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

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

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

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

Кодировка QByteArray
И снова я с очередной порцией странных на первый взгляд вопросов. По UDP получаю пакеты. Пишу...

QQueue и QByteArray
1. У меня есть очередь - QQueue&lt;uchar&gt;. в нее постоянно дописываются данные из сокета. ...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru