Evgenii Legotckoi
Evgenii Legotckoi8 декабря 2015 г. 10:20

Qt/C++ - Урок 034. Echo Server на основе QTcpServer

Для работы со стеком TCP/IP Qt предоставляет классы QTcpServer, QTcpSocket, а также QUdpSocket. Для первого знакомства с работой локальной сети напишем Echo Сервер . Задача эхо сервера отправлять назад к отправителю полученные от него данные, как это делает эхо с человеческим голосом. Для подключения к серверу будет использоваться telnet.

TELNET (англ.  TErminaL NETwork) — сетевой протокол для реализации текстового интерфейса по сети (в современной форме — при помощи транспорта TCP). Название «telnet» имеют также некоторые утилиты, реализующие клиентскую часть протокола.

В предлагаемой программе объект класса QTcpServer будет слушать один из портов стека протоколов TCP/IP от всех хостов в сети. Прослушивание порта устанавливается методом listen() с указанием специфицированного IP-адреса или диапазона IP-адресов, а также порта прослушивания.

Когда происходит подключение клиента к порту вызывается сигнал newConnection() , который будет поключён к слоту slotNewConnection(), в данном слоте будет инициировано подключение клиента в качестве объекта QTcpSocket на стороне сервера с помощью метода nextPendingConnection(), который возвращает указатель на объект QTcpSocket.

К новому сокету будет подключено два слота. Первый слот slotServerRead() будет подключён к сигналу readyRead от сокета и будет вызываться в том случае, если на сокет пришли данные, которые готовы к чтению. Второй слот slotClientDisconnected() подключён к сигналу disconnected() , который вызывается в том случае, когда клиент отключился от сервера и необходимо закрыть соединение со стороны сервера.

Структура проекта для работы с QTcpServer

Будет создано консольное приложение, следовательно классов вроде MainWindow в приложении использовано не будет.

  • EchoServer.pro - профайл проекта;
  • main.cpp - основной файл исходных кодов;
  • mytcpserver.h - заголовочный файл сервера;
  • mytcpserver.cpp - файл исходных кодов сервера;

EchoServer.pro

В данном файле необходимо добавить Qt модуль для работы с сетью.

QT += network

main.cpp

Всё, что нужно сделать в данном файле, это подключить заголовочный файл сервера и создать экземпляр сервера.

#include <QCoreApplication>
#include "mytcpserver.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    MyTcpServer server;

    return a.exec();
}

mytcpserver.h

Данный класс является обёрткой для работы с QTcpServer и наследован от QObject для применения сигналов и слотов .

#ifndef MYTCPSERVER_H
#define MYTCPSERVER_H

#include <QObject>
#include <QTcpServer>
#include <QTcpSocket>

class MyTcpServer : public QObject
{
    Q_OBJECT
public:
    explicit MyTcpServer(QObject *parent = 0);

public slots:
    void slotNewConnection();
    void slotServerRead();
    void slotClientDisconnected();

private:
    QTcpServer * mTcpServer;
    QTcpSocket * mTcpSocket;
};

#endif // MYTCPSERVER_H

mytcpserver.cpp

#include "mytcpserver.h"
#include <QDebug>
#include <QCoreApplication>

MyTcpServer::MyTcpServer(QObject *parent) : QObject(parent)
{
    mTcpServer = new QTcpServer(this);

    connect(mTcpServer, &QTcpServer::newConnection, this, &MyTcpServer::slotNewConnection);

    if(!mTcpServer->listen(QHostAddress::Any, 6000)){
        qDebug() << "server is not started";
    } else {
        qDebug() << "server is started";
    }
}

void MyTcpServer::slotNewConnection()
{
    mTcpSocket = mTcpServer->nextPendingConnection();

    mTcpSocket->write("Hello, World!!! I am echo server!\r\n");

    connect(mTcpSocket, &QTcpSocket::readyRead, this, &MyTcpServer::slotServerRead);
    connect(mTcpSocket, &QTcpSocket::disconnected, this, &MyTcpServer::slotClientDisconnected);
}

void MyTcpServer::slotServerRead()
{
    while(mTcpSocket->bytesAvailable()>0)
    {
        QByteArray array = mTcpSocket->readAll();

        mTcpSocket->write(array);
    }
}

void MyTcpServer::slotClientDisconnected()
{
    mTcpSocket->close();
}

Работа с Echo Server

После того, как Вы соберёте проект и у Вас запустится консольное приложение, воспользуйтесь любым программным обеспечением, которое поддерживает telnet, например Putty, и подключитесь на настроенный порт. Попробуйте отослать данные сервер, чтобы убедиться, что он Вам их вернёт. В некоторых случаях этого может не произойти или Вы вообще не сможете подключиться, тогда отключите FireWall, часто проблема скрывается именно в нём.

Демонстрация работы приложения с дополнительными комментариями представлена в видеоуроке.

Ссылка на скачивание проекта в zip-архиве: echoserver.zip

Видеоурок

Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

Вам это нравится? Поделитесь в социальных сетях!

ИВ
  • 15 марта 2021 г. 14:46
  • (ред.)

Добрый день, разрешите вопрос:
во всех примерах работы с QTcpServer его всегда создают в main.cpp, нет ли возможности корректно сохдать его в MainWindow.cpp ?
Просто если перенести код в MainWindow.cpp

#include "myserver.h"

MainWindow::MainWindow( QWidget *parent): QMainWindow(parent) , ui(new Ui::MainWindow)
{
    myserver Server;
    Server.startServer();
    ui->setupUi(this);

то возникает ошибка на клиенте QNativeSocketEngine::write() was not called in QAbstractSocket::ConnectedState

Evgenii Legotckoi
  • 2 июля 2021 г. 6:36

Переменную myserver нужно объявить в заголовочном файле, в противном случае после выполнения конструктора окна эта переменная удаляется, поскольку создана на стеке конструктора.

ИВ
  • 2 июля 2021 г. 6:51

спасибо, но уже не актуально. Я уже написал классы многопоточного сервера и они переносимы, раскидал их по четырем приложениям, даже не меняя код.

e
  • 16 августа 2021 г. 12:43

Hi, great post.

If I were to reimplement QTcpServer for the purposes of SSL, shouldn't incomingConnection(int socket) just be automatically called after a connection occurs?

Комментарии

Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь
m
  • molni99
  • 26 октября 2024 г. 8:37

C++ - Тест 004. Указатели, Массивы и Циклы

  • Результат:80баллов,
  • Очки рейтинга4
m
  • molni99
  • 26 октября 2024 г. 8:29

C++ - Тест 004. Указатели, Массивы и Циклы

  • Результат:20баллов,
  • Очки рейтинга-10

C++ - Тест 003. Условия и циклы

  • Результат:42баллов,
  • Очки рейтинга-8
Последние комментарии
A
ALO1ZE19 октября 2024 г. 15:19
Читалка fb3-файлов на Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
ИМ
Игорь Максимов5 октября 2024 г. 14:51
Django - Урок 064. Как написать расширение для Python Markdown Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
d
dblas55 июля 2024 г. 18:02
QML - Урок 016. База данных SQLite и работа с ней в QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
k
kmssr9 февраля 2024 г. 1:43
Qt Linux - Урок 001. Автозапуск Qt приложения под Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
АК
Анатолий Кононенко5 февраля 2024 г. 8:50
Qt WinAPI - Урок 007. Работаем с ICMP Ping в Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
Сейчас обсуждают на форуме
jd
jasmine disouza28 октября 2024 г. 10:58
GeForce Now India: Unlocking the Future of Cloud Gaming GeForce Now India has a major impact on the gaming scene by introducing NVIDIA's cloud gaming service to Indian gamers. GeForce Now India lets you stream top-notch PC games on any device, from b…
9
9Anonim25 октября 2024 г. 16:10
Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…
J
JacobFib17 октября 2024 г. 10:27
добавить qlineseries в функции Пользователь может получить любые разъяснения по интересующим вопросам, касающимся обработки его персональных данных, обратившись к Оператору с помощью электронной почты https://topdecorpro.ru…
ИМ
Игорь Максимов3 октября 2024 г. 11:05
Реализация навигации по разделам Спасибо Евгений!
JW
Jhon Wick1 октября 2024 г. 22:52
Indian Food Restaurant In Columbus OH| Layla’s Kitchen Indian Restaurant If you're looking for a truly authentic https://www.laylaskitchenrestaurantohio.com/ , Layla’s Kitchen Indian Restaurant is your go-to destination. Located at 6152 Cleveland Ave, Colu…

Следите за нами в социальных сетях