Qt5 Tutorial QTcpSocket with Signals and Slots - 2020
In this tutorial, we will learn how to download a file using QTcpSocket. This is a continued tutorial from the previous one, Qt 5 QTcpSocket. We're going to use Signal and Slot mechanism instead of calling functions manually(?).
Note: Qt5 document
The QTcpSocket class provides a TCP socket.
TCP (Transmission Control Protocol) is a reliable, stream-oriented, connection-oriented transport protocol. It is especially well suited for continuous transmission of data.
QTcpSocket is a convenience subclass of QAbstractSocket that allows you to establish a TCP connection and transfer streams of data. See the QAbstractSocket documentation for details.
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, QTcpSocket.pro:
QT += core QT += network QT -= gui TARGET = QTcpSocket CONFIG += console CONFIG -= app_bundle TEMPLATE = app SOURCES += main.cpp
Then, we want to create a new class called MyTcpSocket.
Let's do work on main.cpp.
We need to create an instance of MyTcpSocket, and then call a our key driver function call, doConnect():
// main.cpp #include#include "mytcpsocket.h" int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); MyTcpSocket s; s.doConnect(); return a.exec(); }
Now, let's implement the doConnect() method. But before doing that we should write some lines of code in the mytcpsocket.h:
- #include <QTcpSocket>
- the prototype of the method, doConnect()
- Socket object (pointer)
#ifndef MYTCPSOCKET_H #define MYTCPSOCKET_H #include <QObject> #include <QTcpSocket> #include <QAbstractSocket> #include <QDebug> class MyTcpSocket : public QObject { Q_OBJECT public: explicit MyTcpSocket(QObject *parent = 0); void doConnect(); signals: public slots: void connected(); void disconnected(); void bytesWritten(qint64 bytes); void readyRead(); private: QTcpSocket *socket; }; #endif // MYTCPSOCKET_H
Once header file is done, let's move on to implementation file, mytcpsocket.cpp:
// mytcpsocket.cpp #include "mytcpsocket.h" MyTcpSocket::MyTcpSocket(QObject *parent) : QObject(parent) { } void MyTcpSocket::doConnect() { socket = new QTcpSocket(this); connect(socket, SIGNAL(connected()),this, SLOT(connected())); connect(socket, SIGNAL(disconnected()),this, SLOT(disconnected())); connect(socket, SIGNAL(bytesWritten(qint64)),this, SLOT(bytesWritten(qint64))); connect(socket, SIGNAL(readyRead()),this, SLOT(readyRead())); qDebug() << "connecting..."; // this is not blocking call socket->connectToHost("google.com", 80); // we need to wait... if(!socket->waitForConnected(5000)) { qDebug() << "Error: " << socket->errorString(); } } void MyTcpSocket::connected() { qDebug() << "connected..."; // Hey server, tell me about you. socket->write("HEAD / HTTP/1.0\r\n\r\n\r\n\r\n"); } void MyTcpSocket::disconnected() { qDebug() << "disconnected..."; } void MyTcpSocket::bytesWritten(qint64 bytes) { qDebug() << bytes << " bytes written..."; } void MyTcpSocket::readyRead() { qDebug() << "reading..."; // read the data from the socket qDebug() << socket->readAll(); }
The void QAbstractSocket::connectToHost(const QString & hostName, quint16 port, OpenMode openMode = ReadWrite, NetworkLayerProtocol protocol = AnyIPProtocol) function attempts to make a connection to hostName on the given port. The protocol parameter can be used to specify which network protocol to use (eg. IPv4 or IPv6).
The socket is opened in the given openMode and first enters HostLookupState, then performs a host name lookup of hostName. If the lookup succeeds, hostFound() is emitted and QAbstractSocket enters ConnectingState. It then attempts to connect to the address or addresses returned by the lookup. Finally, if a connection is established, QAbstractSocket enters ConnectedState and emits connected().
At any point, the socket can emit error() to signal that an error occurred.
The hostName may be an IP address in string form (e.g., "43.195.83.32"), or it may be a host name (e.g., "example.com"). QAbstractSocket will do a lookup only if required. port is in native byte order.
The bool QAbstractSocket::waitForConnected(int msecs = 30000) waits until the socket is connected, up to msecs milliseconds. If the connection has been established, this function returns true; otherwise it returns false. In the case where it returns false, we can call error() to determine the cause of the error.
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.
The bool QAbstractSocket::waitForReadyRead(int msecs = 30000) is reimplemented from QIODevice::waitForReadyRead().
This function blocks until new data is available for reading and the readyRead() signal has been emitted. The function will timeout after msecs milliseconds; the default timeout is 30000 milliseconds.
The function returns true if the readyRead() signal is emitted and there is new data available for reading; otherwise it returns false (if an error occurred or the operation timed out).
The qint64 QAbstractSocket::bytesAvailable() const is reimplemented from QIODevice::bytesAvailable().
This function eturns the number of incoming bytes that are waiting to be read.
The QByteArray QIODevice::readAll() reads all available data from the device, and returns it as a QByteArray.
Run the code, then we get:
connecting... connected... 23 bytes written... reading... "HTTP/1.0 200 OK Date: Wed, 18 Sep 2013 16:30:03 GMT Expires: -1 Cache-Control: private, max-age=0 Content-Type: text/html; charset=ISO-8859-1 Set-Cookie: PREF=ID=c90a5b4f9f1a49f2:FF=0:TM=1379521803:LM=1379521803:S=uB_DHUgs cgGzryP6; expires=Fri, 18-Sep-2015 16:30:03 GMT; path=/; domain=.google.com Set-Cookie: NID=67=Ms_cR4zdNEnW3NUkq9oE3nHt7pyMAsQ4HHA1vKpbehn1xDHXUnMao7XUwsue0 xLOvqEyFU3zgGhH1l1ECVzyBcJzyHVzPVI5Z4FBD3cCEwmpFrHqDfF_4Rlr0s4yfOLP; expires=Thu , 20-Mar-2014 16:30:03 GMT; path=/; domain=.google.com; HttpOnly P3P: CP="This is not a P3P policy! See //www.google.com/support/accounts/bi n/answer.py?hl=en&answer=151657 for more info." Server: gws X-XSS-Protection: 1; mode=block X-Frame-Options: SAMEORIGIN Alternate-Protocol: 80:quic " disconnected...
Here are the files used in this tutorial.
We can get it from TcpSocket.zip.
main.cpp:
#include <QCoreApplication> #include "mytcpsocket.h" int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); MyTcpSocket s; s.doConnect(); return a.exec(); }
mytcpsocket.h:
#ifndef MYTCPSOCKET_H #define MYTCPSOCKET_H #include <QObject> #include <QTcpSocket> #include <QAbstractSocket> #include <QDebug> class MyTcpSocket : public QObject { Q_OBJECT public: explicit MyTcpSocket(QObject *parent = 0); void doConnect(); signals: public slots: void connected(); void disconnected(); void bytesWritten(qint64 bytes); void readyRead(); private: QTcpSocket *socket; }; #endif // MYTCPSOCKET_H
mytcpsocket.cpp:
#include "mytcpsocket.h" MyTcpSocket::MyTcpSocket(QObject *parent) : QObject(parent) { } void MyTcpSocket::doConnect() { socket = new QTcpSocket(this); connect(socket, SIGNAL(connected()),this, SLOT(connected())); connect(socket, SIGNAL(disconnected()),this, SLOT(disconnected())); connect(socket, SIGNAL(bytesWritten(qint64)),this, SLOT(bytesWritten(qint64))); connect(socket, SIGNAL(readyRead()),this, SLOT(readyRead())); qDebug() << "connecting..."; // this is not blocking call socket->connectToHost("google.com", 80); // we need to wait... if(!socket->waitForConnected(5000)) { qDebug() << "Error: " << socket->errorString(); } } void MyTcpSocket::connected() { qDebug() << "connected..."; // Hey server, tell me about you. socket->write("HEAD / HTTP/1.0\r\n\r\n\r\n\r\n"); } void MyTcpSocket::disconnected() { qDebug() << "disconnected..."; } void MyTcpSocket::bytesWritten(qint64 bytes) { qDebug() << bytes << " bytes written..."; } void MyTcpSocket::readyRead() { qDebug() << "reading..."; // read the data from the socket qDebug() << socket->readAll(); }
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