06 progressBar->hide();

07 }

Закрытая функция closeConnection() закрывает соединение сервера TCP и обновляет интерфейс пользователя. Она вызывается из функции updateTableWidget(), когда считывается значение 0xFFFF, и из нескольких других слотов, которые мы вскоре рассмотрим.

01 void TripPlanner::stopSearch()

02 {

03 statusLabel->setText(tr("Search stopped"));

04 closeConnection();

05 }

Слот stopSearch() подсоединяется к сигналу clicked() кнопки Stop. По существу, он просто вызывает функцию closeConnection().

01 void TripPlanner::connectionClosedByServer()

02 {

03 if (nextBlockSize != 0xFFFF)

04 statusLabel->setText(tr("Error: Connection closed by server" ));

05 closeConnection();

06 }

Слот connectionClosedByServer() подсоединяется к сигналу disconnected() объекта QTcpSocket. Если сервер закрывает соединение и мы еще не получили маркер конца, мы уведомляем пользователя о возникновении ошибки. И как обычно, мы вызываем функцию closeConnection() для обновления интерфейса пользователя.

01 void TripPlanner::error()

02 {

03 statusLabel->setText(tcpSocket.errorString());

04 closeConnection();

05 }

Слот error() подсоединяется к сигналу error(QAbstractSocket::SocketError) объекта QTcpSocket. Мы игнорируем код ошибки и используем функцию QTcpSocket::errorString(), которая возвращает понятное человеку сообщение о последней возникшей ошибке.

На этом завершается рассмотрение класса TripPlanner. Функция main() приложения Trip Planner выглядит обычным образом:

01 int main(int argc, char *argv[])

02 {

03 QApplication app(argc, argv);

04 TripPlanner tripPlanner;

05 tripPlanner.show();

06 return app.exec();

07 }

Теперь давайте реализуем сервер. Сервер состоит из двух классов: TripServer и ClientSocket. Класс TripServer наследует QTcpServer — класс, который позволяет нам принимать входящие соединения TCP. Класс ClientSocket переопределяет QTcpSocket и обслуживает одно соединение. В каждый момент времени в памяти имеется ровно столько объектов типа ClientSocket, сколько обслуживается клиентов.

01 class TripServer : public QTcpServer

02 {

03 Q_OBJECT

04 public:

05 TripServer(QObject *parent = 0);

06 private:

07 void incomingConnection(int socketId);

08 };

Класс TripServer переопределяет функцию incomingConnection() из класса QTcpServer. Данная функция вызывается всякий раз, когда клиент пытается подсоединиться к порту, который прослушивает сервер.

01 TripServer::TripServer(QObject *parent)

02 : QTcpServer (parent)

03 {

04 }

Конструктор TripServer тривиален.

01 void TripServer::incomingConnection(int socketId)

02 {

03 ClientSocket *socket = new ClientSocket(this);

04 socket->setSocketDescriptor(socketId);

05 }

В функции incomingConnection() мы создаем объект ClientSocket в качестве дочернего по отношению к объекту TripServer, и мы устанавливаем дескриптор его coкета на переданное нам значение. Объект ClientSocket автоматически удалит сам себя при прекращении соединения.

01 class ClientSocket : public QTcpSocket

02 {

03 Q_OBJECT

04 public:

05 ClientSocket(QObject *parent = 0);

06 private slots:

07 void readClient();

08 private:

09 void generateRandomTrip(const QString &from, const QString &to,

10 const QDate &date, const QTime &time);

11 quint16 nextBlockSize;

12 };

Перейти на страницу:

Похожие книги