Evgenii Legotckoi
Dec. 8, 2015, 9:20 p.m.

Qt/C++ - Lesson 034. Echo Server based on QTcpServer

To work with TCP / IP stack Qt provides QTcpServer, QTcpSocket, and QUdpSocket classes. For the first acquaintance with the work of the local network write Echo server. Task echo server to send back to the sender of the data obtained from it, as does the echo of a human voice. To connect to the server will be used telnet.

TELNET (TErminaL NETwork) — network protocol for the implementation of a text interface on the network (in modern form - using the TCP transport). The name «telnet» also have some tools that implement the client part of the protocol.

The proposed program QTcpServer class object will listen to one of the TCP/IP protocol stack ports from all hosts on the network. Listening port set by listen(), indicating the specified IP-address, or IP-address range, as well as the listening port.

When a client connects to the port we invoke signal newConnection() , which will connects to slot slotNewConnection() , the slot will be initiated by the client connection as QTcpSocket object on the server side using the method nextPendingConnection() , which returns a pointer to the object QTcpSocket .

Two slots will be connected to the new socket. First slotServerRead() slot is connected to the signal readyRead from the socket, and will be called in if the socket on the data came, who are willing to read. The second slot slotClientDisconnected() is connected to the signal disconnected() , which is called in the case when the client is disconnected from the server, and you must close the connection from the server side.

Project structure for work with QTcpServer

This will create a console application, so the classes like MainWindow in the annex will not be used.

  • EchoServer.pro - the profile of the project;
  • main.cpp - the main source file;
  • mytcpserver.h - header file server;
  • mytcpserver.cpp - file server source code;

EchoServer.pro

In this file, you must add the Qt module to work with the network.

  1. QT += network

main.cpp

All you need to do in this file is a header file server and create a server instance.

  1. #include <QCoreApplication>
  2. #include "mytcpserver.h"
  3.  
  4. int main(int argc, char *argv[])
  5. {
  6. QCoreApplication a(argc, argv);
  7.  
  8. MyTcpServer server;
  9.  
  10. return a.exec();
  11. }

mytcpserver.h

This class is a wrapper for a QTcpServer and inherited from QObject for use signals and slots.

  1. #ifndef MYTCPSERVER_H
  2. #define MYTCPSERVER_H
  3.  
  4. #include <QObject>
  5. #include <QTcpServer>
  6. #include <QTcpSocket>
  7.  
  8. class MyTcpServer : public QObject
  9. {
  10. Q_OBJECT
  11. public:
  12. explicit MyTcpServer(QObject *parent = 0);
  13.  
  14. public slots:
  15. void slotNewConnection();
  16. void slotServerRead();
  17. void slotClientDisconnected();
  18.  
  19. private:
  20. QTcpServer * mTcpServer;
  21. QTcpSocket * mTcpSocket;
  22. };
  23.  
  24. #endif // MYTCPSERVER_H

mytcpserver.cpp

  1. #include "mytcpserver.h"
  2. #include <QDebug>
  3. #include <QCoreApplication>
  4.  
  5. MyTcpServer::MyTcpServer(QObject *parent) : QObject(parent)
  6. {
  7. mTcpServer = new QTcpServer(this);
  8.  
  9. connect(mTcpServer, &QTcpServer::newConnection, this, &MyTcpServer::slotNewConnection);
  10.  
  11. if(!mTcpServer->listen(QHostAddress::Any, 6000)){
  12. qDebug() << "server is not started";
  13. } else {
  14. qDebug() << "server is started";
  15. }
  16. }
  17.  
  18. void MyTcpServer::slotNewConnection()
  19. {
  20. mTcpSocket = mTcpServer->nextPendingConnection();
  21.  
  22. mTcpSocket->write("Hello, World!!! I am echo server!\r\n");
  23.  
  24. connect(mTcpSocket, &QTcpSocket::readyRead, this, &MyTcpServer::slotServerRead);
  25. connect(mTcpSocket, &QTcpSocket::disconnected, this, &MyTcpServer::slotClientDisconnected);
  26. }
  27.  
  28. void MyTcpServer::slotServerRead()
  29. {
  30. while(mTcpSocket->bytesAvailable()>0)
  31. {
  32. QByteArray array = mTcpSocket->readAll();
  33.  
  34. mTcpSocket->write(array);
  35. }
  36. }
  37.  
  38. void MyTcpServer::slotClientDisconnected()
  39. {
  40. mTcpSocket->close();
  41. }

Work with Echo Server

Once you compile a project and you run a console application, use any software that supports telnet, such as the Putty , and connect to the configured port. Try to send data to the server, to make sure that he will return them to you. In some cases, this may not happen at all, or you can not connect, then disconnect the FireWall , often the problem lies precisely in it.

Link to the project download in zip-archive: echoserver.zip

Video

Do you like it? Share on social networks!

ИВ
  • March 16, 2021, 12:46 a.m.
  • (edited)

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

  1. #include "myserver.h"
  2.  
  3. MainWindow::MainWindow( QWidget *parent): QMainWindow(parent) , ui(new Ui::MainWindow)
  4. {
  5. myserver Server;
  6. Server.startServer();
  7. ui->setupUi(this);

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

Evgenii Legotckoi
  • July 2, 2021, 4:36 p.m.

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

ИВ
  • July 2, 2021, 4:51 p.m.

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

e
  • Aug. 16, 2021, 10:43 p.m.

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?

Comments

Only authorized users can post comments.
Please, Log in or Sign up
  • Last comments
  • AK
    April 1, 2025, 11:41 a.m.
    Добрый день. В данный момент работаю над проектом, где необходимо выводить звук из программы в определенное аудиоустройство (колонки, наушники, виртуальный кабель и т.д). Пишу на Qt5.12.12 поско…
  • Evgenii Legotckoi
    March 9, 2025, 9:02 p.m.
    К сожалению, я этого подсказать не могу, поскольку у меня нет необходимости в обходе блокировок и т.д. Поэтому я и не задавался решением этой проблемы. Ну выглядит так, что вам действитель…
  • VP
    March 9, 2025, 4:14 p.m.
    Здравствуйте! Я устанавливал Qt6 из исходников а также Qt Creator по отдельности. Все компоненты, связанные с разработкой для Android, установлены. Кроме одного... Когда пытаюсь скомпилиров…
  • ИМ
    Nov. 22, 2024, 9:51 p.m.
    Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
  • Evgenii Legotckoi
    Oct. 31, 2024, 11:37 p.m.
    Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup