Russian Qt Forum

Qt => Работа с сетью => Тема начата: ManOfOrange от Март 21, 2011, 14:03



Название: Передача массива через QTcpSocket
Отправлено: ManOfOrange от Март 21, 2011, 14:03
Приветствую всех!

Есть задача передать массив (какой угодно: int, QString - главное, принцип) через QTcpSocket.
В поиске нашёл тему двухлетней давности - http://www.prog.org.ru/topic_8038_0.html (http://www.prog.org.ru/topic_8038_0.html)

Проблема в том, что в теме обсуждается Qt3. У меня же Qt 4.5.3, и переделать под него у меня не получилось.

Подскажите, пожалуйста, как это можно сделать :-)

P.S. А также интересна передача enum.


Название: Re: Передача массива через QTcpSocket
Отправлено: Пантер от Март 21, 2011, 14:12
Читай про и QByteArray, QDataStream. Смысл в том, что с помощью QDataStream закидываешь данные в QByteArray, который потом и передаешь.
enum - обычное число.


Название: Re: Передача массива через QTcpSocket
Отправлено: ManOfOrange от Март 21, 2011, 14:28
ну, передача переменных у меня работает: брал пример из Бланшетт.
Отправка выглядит примерно так:

Код:
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_5);

QString str = "123";
out << quint16(0) << quint8('S') << str;

out.device()->seek(0);
out << quint16(block.size() - sizeof(quint16));

tcpSocket.write(block);

Ну, и принимаю на другой стороне похожим образом.

А вот как передать массив - не въезжаю вообще. Единственная мысль - записывать поочерёдно в QDataStream значения элементов массива, а потом их считывать и загонять в массив, но мне кажется это не совсем правильным :-)


Название: Re: Передача массива через QTcpSocket
Отправлено: SimpleSunny от Март 21, 2011, 14:41
Это нормальное решение. Из исходников qt

Код
C++ (Qt)
template<typename T>
QDataStream& operator>>(QDataStream& s, QVector<T>& v)
{
   v.clear();
   quint32 c;
   s >> c;
   v.resize(c);
   for(quint32 i = 0; i < c; ++i) {
       T t;
       s >> t;
       v[i] = t;
   }
   return s;
}
 
template<typename T>
QDataStream& operator<<(QDataStream& s, const QVector<T>& v)
{
   s << quint32(v.size());
   for (typename QVector<T>::const_iterator it = v.begin(); it != v.end(); ++it)
       s << *it;
   return s;
}


Название: Re: Передача массива через QTcpSocket
Отправлено: vebmaster от Май 13, 2020, 20:09
Код:
out << quint16(0) << quint8('S') << str;
А зачем добавляют quint8('S')? Что это даёт?


Название: Re: Передача массива через QTcpSocket
Отправлено: Авварон от Май 13, 2020, 20:54
Размер чара не гарантированно равен 8 битам (я, правда, не слышал об платформах где бы этот было не так).
Кроме того, чар бывает знаковый и беззнаковый и вот это вполне может быть.
Таким образом мы хотим убедиться что мы обязательно запишем _беззнаковое_ целое размером 8 бит а не как повезет на нашей платформе.


Название: Re: Передача массива через QTcpSocket
Отправлено: vebmaster от Май 17, 2020, 09:34
Таким образом мы хотим убедиться что мы обязательно запишем _беззнаковое_ целое размером 8 бит
Так если записали 1 char, а после него QString, то и считывать мы будем так же, 1 char, а после него уже QString. Правильно?
Если так, тогда опять непонято зачем нужен этот S


Название: Re: Передача массива через QTcpSocket
Отправлено: Igors от Май 17, 2020, 10:55
Таким образом мы хотим убедиться что мы обязательно запишем _беззнаковое_ целое размером 8 бит а не как повезет на нашей платформе.
Размером 8 бит - да, и лучше указать тип явно (хз есть ли оператор именно для (u)char), а вот писать можно как знаковое так и без, прочтется верно т.к. их внутренние представления одинаковы. К слову
Код
C++ (Qt)
unsigned char r, g, b;
...
unsigned char aver = (r + g + b) / 3;
 
Корректен ли этот код?

Так если записали 1 char, а после него QString, то и считывать мы будем так же, 1 char, а после него уже QString. Правильно?
Если так, тогда опять непонято зачем нужен этот S
Да, никакой смысловой нагрузки 'S' не несет, просто для примера