Qt5 Tutorial QTcpServer - 2020
In this tutorial, we will learn how to setup Client and Server using QTcpServer in an asynchronous (non-blocking) mode.
Note: Qt5 document
The QTcpServer class provides a TCP-based server.
This class makes it possible to accept incoming TCP connections. You can specify the port or have QTcpServer pick one automatically. You can listen on a specific address or on all the machine's addresses.
Call listen() to have the server listen for incoming connections. The newConnection() signal is then emitted each time a client connects to the server.
Call nextPendingConnection() to accept the pending connection as a connected QTcpSocket. The function returns a pointer to a QTcpSocket in QAbstractSocket::ConnectedState that you can use for communicating with the client.
If an error occurs, serverError() returns the type of error, and errorString() can be called to get a human readable description of what happened.
When listening for connections, the address and port on which the server is listening are available as serverAddress() and serverPort().
Calling close() makes QTcpServer stop listening for incoming connections. Although QTcpServer is mostly designed for use with an event loop, it's possible to use it without one. In that case, you must use waitForNewConnection(), which blocks until either a connection is available or a timeout expires.
For TCP Socket in general, please visit my C++ Tutorials: Socket - Server and Client.
We'll start with Qt Console Application.
First, we need to add network module to our project file, QTcpServer.pro:
QT += core QT += network QT -= gui TARGET = TcpServer CONFIG += console CONFIG -= app_bundle TEMPLATE = app SOURCES += main.cpp
Then, we want to create a new class called MyTcpServer.
Let's do work on main.cpp.
We need to create an instance of MyTcpServer. Then, in the constructor of MyTcpServer, an instance of QTcpServer will be created, and the server will be started.
// main.cpp #include#include "mytcpserver.h" int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // create MyTcpServer // MyTcpServer constructor will create QTcpServer MyTcpServer server; return a.exec(); }
Now, let's write some lines of code in the mytcpserver.h:
- #include <QTcpSocket> and <QTcpServer>
- public slot, newConnection()
- Server object (pointer)
#ifndef MYTCPSERVER_H #define MYTCPSERVER_H #include <QObject> #include <QTcpSocket> #include <QTcpServer> #include <QDebug> class MyTcpServer : public QObject { Q_OBJECT public: explicit MyTcpServer(QObject *parent = 0); signals: public slots: void newConnection(); private: QTcpServer *server; }; #endif // MYTCPSERVER_H
The void QTcpServer::newConnection() signal is emitted every time a new connection is available.
So, header file is done, let's move on to implementation file, mytcpserver.cpp:
// mytcpserver.cpp #include "mytcpserver.h" MyTcpServer::MyTcpServer(QObject *parent) : QObject(parent) { server = new QTcpServer(this); // whenever a user connects, it will emit signal connect(server, SIGNAL(newConnection()), this, SLOT(newConnection())); if(!server->listen(QHostAddress::Any, 9999)) { qDebug() << "Server could not start"; } else { qDebug() << "Server started!"; } } void MyTcpServer::newConnection() { // need to grab the socket QTcpSocket *socket = server->nextPendingConnection(); socket->write("Hello client\r\n"); socket->flush(); socket->waitForBytesWritten(3000); socket->close(); }
The QTcpSocket * QTcpServer::nextPendingConnection() returns the next pending connection as a connected QTcpSocket object.
The socket is created as a child of the server, which means that it is automatically deleted when the QTcpServer object is destroyed. It is still a good idea to delete the object explicitly when you are done with it, to avoid wasting memory.
0 is returned if this function is called when there are no pending connections.
Note: The returned QTcpSocket object cannot be used from another thread. If you want to use an incoming connection from another thread, you need to override incomingConnection().
Also note that in this example we're using asynchronous mode of QTcpSever. QTcpServer has a listen() method which returns immediately. If listening started successfully the server will emit the signal newConnection(). After calling listen(), it does not call waitForNewConnection() which is a blocking method (synchronous). So, in this example, to emit a newConnection() signal for every incoming request, behind the scene, there must be an event loop running(QEventLoop and QAbstractEventDispatcher).
For buffered devices, the bool QIODevice::waitForBytesWritten(int msecs) function waits until a payload of buffered written data has been written to the device and the bytesWritten() signal has been emitted, or until msecs milliseconds have passed. If msecs is -1, this function will not time out. For unbuffered devices, it returns immediately.
It returns true if a payload of data was written to the device; otherwise returns false (i.e. if the operation timed out, or if an error occurred).
This function can operate without an event loop. It is useful when writing non-GUI applications and when performing I/O operations in a non-GUI thread.
Run our code.
The main() will create a MyTcpServer instance, and then the MyTcpServer constructor will create QTcpServer.
The the server started and it is listening if there is any connection request from a client:
Then, the client tries to connect to the server using telnet.
If you're on Windows, and telnet is not available, go to Control Panel->Programs->Turn Windows Features on and off:
Mark Telnet Client as checked:
Here are the screen shots from a client:
As we can see from the picture below, the client did telnet to loopback (127.0.0.1) with the listening port 9999, and got the response from the server "Hello client" but lost the connection.
That's exactly what they're supposed to behave. The server sends the message to the connected client, and immediately after that, the server close the connection!
Here are the files used in this tutorial.
We can get it from TcpServer.zip.
main.cpp:
#include <QCoreApplication> #include "mytcpserver.h" int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // create MyTcpServer // MyTcpServer constructor will create QTcpServer MyTcpServer server; return a.exec(); }
mytcpserver.h:
#ifndef MYTCPSERVER_H #define MYTCPSERVER_H #include <QObject> #include <QTcpSocket> #include <QTcpServer> #include <QDebug> class MyTcpServer : public QObject { Q_OBJECT public: explicit MyTcpServer(QObject *parent = 0); signals: public slots: void newConnection(); private: QTcpServer *server; }; #endif // MYTCPSERVER_H
mytcpserver.cpp:
#include "mytcpserver.h" MyTcpServer::MyTcpServer(QObject *parent) : QObject(parent) { server = new QTcpServer(this); // whenever a user connects, it will emit signal connect(server, SIGNAL(newConnection()), this, SLOT(newConnection())); if(!server->listen(QHostAddress::Any, 9999)) { qDebug() << "Server could not start"; } else { qDebug() << "Server started!"; } } void MyTcpServer::newConnection() { // need to grab the socket QTcpSocket *socket = server->nextPendingConnection(); socket->write("Hello client\r\n"); socket->flush(); socket->waitForBytesWritten(3000); socket->close(); }
Video recording - Producer and Consumer model using QSemaphore
- QHttp - Downloading Files
- QNetworkAccessManager and QNetworkRequest - Downloading Files
- QUdpSocket
- QTcpSocket
- QTcpSocket with Signals and Slots
- QTcpServer - Client and Server
- QTcpServer - Loopback Dialog
- QTcpServer - Client and Server using MultiThreading
- QTcpServer - Client and Server using QThreadPool
- Asynchronous QTcpServer - Client and Server using QThreadPool
- QThreads - Introduction
- QThreads - Creating Threads
- Creating QThreads using QtConcurrent
- QThreads - Priority
- QThreads - QMutex
- QThreads - GuiThread
- QtConcurrent QProgressDialog with QFutureWatcher
- QSemaphores - Producer and Consumer
- QThreads - wait()
Qt 5 Tutorial
- Hello World
- Signals and Slots
- Q_OBJECT Macro
- MainWindow and Action
- MainWindow and ImageViewer using Designer A
- MainWindow and ImageViewer using Designer B
- Layouts
- Layouts without Designer
- Grid Layouts
- Splitter
- QDir
- QFile (Basic)
- Resource Files (.qrc)
- QComboBox
- QListWidget
- QTreeWidget
- QAction and Icon Resources
- QStatusBar
- QMessageBox
- QTimer
- QList
- QListIterator
- QMutableListIterator
- QLinkedList
- QMap
- QHash
- QStringList
- QTextStream
- QMimeType and QMimeDatabase
- QFile (Serialization I)
- QFile (Serialization II - Class)
- Tool Tips in HTML Style and with Resource Images
- QPainter
- QBrush and QRect
- QPainterPath and QPolygon
- QPen and Cap Style
- QBrush and QGradient
- QPainter and Transformations
- QGraphicsView and QGraphicsScene
- Customizing Items by inheriting QGraphicsItem
- QGraphicsView Animation
- FFmpeg Converter using QProcess
- QProgress Dialog - Modal and Modeless
- QVariant and QMetaType
- QtXML - Writing to a file
- QtXML - QtXML DOM Reading
- QThreads - Introduction
- QThreads - Creating Threads
- Creating QThreads using QtConcurrent
- QThreads - Priority
- QThreads - QMutex
- QThreads - GuiThread
- QtConcurrent QProgressDialog with QFutureWatcher
- QSemaphores - Producer and Consumer
- QThreads - wait()
- MVC - ModelView with QListView and QStringListModel
- MVC - ModelView with QTreeView and QDirModel
- MVC - ModelView with QTreeView and QFileSystemModel
- MVC - ModelView with QTableView and QItemDelegate
- QHttp - Downloading Files
- QNetworkAccessManager and QNetworkRequest - Downloading Files
- Qt's Network Download Example - Reconstructed
- QNetworkAccessManager - Downloading Files with UI and QProgressDialog
- QUdpSocket
- QTcpSocket
- QTcpSocket with Signals and Slots
- QTcpServer - Client and Server
- QTcpServer - Loopback Dialog
- QTcpServer - Client and Server using MultiThreading
- QTcpServer - Client and Server using QThreadPool
- Asynchronous QTcpServer - Client and Server using QThreadPool
- Qt Quick2 QML Animation - A
- Qt Quick2 QML Animation - B
- Short note on Ubuntu Install
- OpenGL with QT5
- Qt5 Webkit : Web Browser with QtCreator using QWebView Part A
- Qt5 Webkit : Web Browser with QtCreator using QWebView Part B
- Video Player with HTML5 QWebView and FFmpeg Converter
- Qt5 Add-in and Visual Studio 2012
- Qt5.3 Installation on Ubuntu 14.04
- Qt5.5 Installation on Ubuntu 14.04
- Short note on deploying to Windows
Ph.D. / Golden Gate Ave, San Francisco / Seoul National Univ / Carnegie Mellon / UC Berkeley / DevOps / Deep Learning / Visualization