Вход/Регистрация
QT 4: программирование GUI на С++
вернуться

Саммерфилд Марк

Шрифт:

12 };

Класс ClientSocket наследует QTcpSocket и инкапсулирует состояние одного клиента.

01 ClientSocket::ClientSocket(QObject *parent)

02 : QTcpSocket(parent)

03 {

04 connect(this, SIGNAL(readyRead), this, SLOT(readClient));

05 connect(this, SIGNAL(disconnected), this, SLOT(deleteLater));

06 nextBlockSize = 0;

07 }

В конструкторе мы устанавливаем необходимые соединения сигнал—слот и задаем переменной nextBlockSize значение 0, свидетельствующее о том, что мы еще не знаем размер посланного клиентом блока.

Сигнал disconnected подсоединяется к функции deleteLater, которая наследуется от класса QObject, и удаляет объект после возврата управления в цикл обработки событий Qt. Это обеспечивает удаление объекта ClientSocket после закрытия сокетного соединения.

01 void ClientSocket::readClient

02 {

03 QDataStream in(this);

04 in.setVersion(QDataStream::Qt_4_1);

05 if (nextBlockSize == 0) {

06 if (bytesAvailable < sizeof(quint16))

07 return;

08 in >> nextBlockSize;

09 }

10 if (bytesAvailable < nextBlockSize)

11 return;

12 quint8 requestType;

13 QString from;

14 QString to;

15 QDate date;

16 QTime time;

17 quint8 flag;

18 in >> requestType;

19 if (requestType == 'S') {

20 in >> from >> to >> date >> time >> flag;

21 srand(from.length * 3600 + to.length * 60 + time.hour);

22 int numTrips = rand % 8;

23 for (int i = 0; i < numTrips; ++i)

24 generateRandomTrip(from, to, date, time);

25 QDataStream out(this);

26 out << quint16(0xFFFF);

27 }

28 close;

29 }

Слот readClient подсоединяется к сигналу readyRead класса QTcpSocket. Если nextBlockSize равен 0, мы начинаем считывать размер блока; в противном случае он уже считан нами, и тогда мы проверяем поступление целого блока. Если это целый блок, мы считываем его за один шаг. Мы используем QDataStream непосредственно для QTcpSocket (объект this) и считываем поля, используя оператор >>.

После чтения запроса клиента мы готовы сформировать ответ. В реальном приложении мы осуществляли бы поиск информации в базе данных расписания железнодорожных рейсов и попытались бы найти подходящие рейсы. Но здесь мы воспользуемся функцией generateRandomTrip, которая случайным образом генерирует произвольный рейс. Мы вызываем эту функцию произвольное число раз и затем посылаем 0xFFFF для обозначения конца данных. В конце мы закрываем соединение.

01 void ClientSocket::generateRandomTrip(const QString & /* откуда */,

02 const QString & /* куда */, const QDate &date, const QTime &time)

03 {

04 QByteArray block;

05 QDataStream out(&block, QIODevice::WriteOnly);

06 out.setVersion(QDataStream::Qt_4_1);

07 quint16 duration = rand % 200;

08 out << quint16(0) << date << time << duration << quint8(1)

09 << QString("InterCity");

10 out.device->seek(0);

11 out << quint16(block.size - sizeof(quint16));

12 write(block);

13 }

Функция generateRandomTrip демонстрирует способ пересылки блока данных через соединение TCP. Это очень напоминает то, что мы делали в клиенте в функции sendRequest. И вновь мы записываем блок в массив QByteArray таким образом, что мы можем определять его размер до того, как мы его отошлем с помощью функции write.

  • Читать дальше
  • 1
  • ...
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: