QT 4: программирование GUI на С++
Шрифт:
Закрытая функция closeConnection закрывает соединение сервера TCP и обновляет интерфейс пользователя. Она вызывается из функции updateTableWidget, когда считывается значение 0xFFFF, и из нескольких других слотов, которые мы вскоре рассмотрим.
Слот stopSearch подсоединяется
Слот connectionClosedByServer подсоединяется к сигналу disconnected объекта QTcpSocket. Если сервер закрывает соединение и мы еще не получили маркер конца, мы уведомляем пользователя о возникновении ошибки. И как обычно, мы вызываем функцию closeConnection для обновления интерфейса пользователя.
Слот error подсоединяется к сигналу error(QAbstractSocket::SocketError) объекта QTcpSocket. Мы игнорируем код ошибки и используем функцию QTcpSocket::errorString, которая возвращает понятное человеку сообщение о последней возникшей ошибке.
На этом завершается рассмотрение класса TripPlanner. Функция main приложения Trip Planner выглядит обычным образом:
Теперь давайте реализуем сервер. Сервер состоит из двух классов: TripServer и ClientSocket. Класс TripServer наследует QTcpServer — класс, который позволяет нам принимать входящие соединения TCP. Класс ClientSocket переопределяет QTcpSocket и обслуживает одно соединение. В каждый момент времени в памяти имеется ровно столько объектов типа ClientSocket, сколько обслуживается клиентов.
Класс TripServer переопределяет
Конструктор TripServer тривиален.
В функции incomingConnection мы создаем объект ClientSocket в качестве дочернего по отношению к объекту TripServer, и мы устанавливаем дескриптор его coкета на переданное нам значение. Объект ClientSocket автоматически удалит сам себя при прекращении соединения.
Класс ClientSocket наследует QTcpSocket и инкапсулирует состояние одного клиента.
В конструкторе мы устанавливаем необходимые соединения сигнал—слот и задаем переменной nextBlockSize значение 0, свидетельствующее о том, что мы еще не знаем размер посланного клиентом блока.
Сигнал disconnected подсоединяется к функции deleteLater, которая наследуется от класса QObject, и удаляет объект после возврата управления в цикл обработки событий Qt. Это обеспечивает удаление объекта ClientSocket после закрытия сокетного соединения.