Qt5 Tutorial QTcpSocket - 2020
In this tutorial, we will learn how to download a file using QTcpSocket. We're taking blocking approach (synchronous). In other words, we use waitFor...() functions (e.g., QTcpSocket::waitForConnected()) until the operation has completed, instead of connecting to signals.
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 <QDebug> class MyTcpSocket : public QObject { Q_OBJECT public: explicit MyTcpSocket(QObject *parent = 0); void doConnect(); signals: public slots: private: QTcpSocket *socket; }; #endif // MYTCPSOCKET_H
Once header file is done, let's move on to implementation file, mytcpsocket.cpp:
#include "mytcpsocket.h" MyTcpSocket::MyTcpSocket(QObject *parent) : QObject(parent) { } void MyTcpSocket::doConnect() { socket = new QTcpSocket(this); socket->connectToHost("google.com", 80); if(socket->waitForConnected(5000)) { qDebug() << "Connected!"; // send socket->write("Hello server\r\n\r\n"); socket->waitForBytesWritten(1000); socket->waitForReadyRead(3000); qDebug() << "Reading: " << socket->bytesAvailable(); // get the data qDebug() << socket->readAll(); // close the connection socket->close(); } else { qDebug() << "Not connected!"; } }
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 returns 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:
Connected! Reading: 1068 "HTTP/1.0 400 Bad Request Content-Type: text/html; charset=UTF-8 Content-Length: 925 Date: Wed, 18 Sep 2013 05:09:31 GMT Server: GFE/2.0 <!DOCTYPE html> <html lang=en> <meta charset=utf-8> <meta name=viewport content="initial-scale=1, minimum-scale=1, width=device-wi dth"> <title>Error 400 (Bad Request)!!1</title> <style> *{margin:0;padding:0}html,code{font:15px/22px arial,sans-serif}html{backgrou nd:#fff;color:#222;padding:15px}body{margin:7% auto 0;max-width:390px;min-height :180px;padding:30px 0 15px}* > body{background:url(//www.google.com/images/error s/robot.png) 100% 5px no-repeat;padding-right:205px}p{margin:11px 0 22px;overflo w:hidden}ins{color:#777;text-decoration:none}a img{border:0}@media screen and (m ax-width:772px){body{background:none;margin-top:0;max-width:none;padding-right:0 }} </style> <a href=//www.google.com/><img src=//www.google.com/images/errors/logo_sm.gif alt=Google></a> <p><b>400.</b> <ins>ThatÆs an error.</ins> <p>Your client has issued a malformed or illegal request. <ins>ThatÆs all we know.</ins> "
Here are the files used in this tutorial.
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 <QDebug> class MyTcpSocket : public QObject { Q_OBJECT public: explicit MyTcpSocket(QObject *parent = 0); void doConnect(); signals: public slots: private: QTcpSocket *socket; }; #endif // MYTCPSOCKET_H
mytcpsocket.cpp:
#include "mytcpsocket.h" MyTcpSocket::MyTcpSocket(QObject *parent) : QObject(parent) { } void MyTcpSocket::doConnect() { socket = new QTcpSocket(this); socket->connectToHost("google.com", 80); if(socket->waitForConnected(5000)) { qDebug() << "Connected!"; // send socket->write("Hello server\r\n\r\n"); socket->waitForBytesWritten(1000); socket->waitForReadyRead(3000); qDebug() << "Reading: " << socket->bytesAvailable(); // get the data qDebug() << socket->readAll(); // close the connection socket->close(); } else { qDebug() << "Not connected!"; } }
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