Qt network programming to realize TCP communication

Qt network programming to realize TCP communication

Labels (space delimited): Tcp communication

1, Introduction to Tcp

  • (1) TCP (Transmission Control Protocol) TCP is a transport layer network protocol for data transmission. Several network protocols include (HTTP and FTP are based on TCP protocol). TCP is a reliable transport protocol for data flow and connection, which is different from another transport layer protocol UDP (see Qt for details - simple UDP communication) .

  • (2) QTcpSocket inherits from QAbstractSocket. Different from the datagram transmitted by QUdpSocket, QTcpSocket transmits continuous data stream, especially suitable for continuous data transmission. TCP is generally divided into client and server, i.e. C/S (Client/Server model).

  • (3) QTcpSocket represents two independent data streams. One is used to read data and the other is used to write data. QTcpSocket::read() and QTcpSocket::write() operations are used respectively. Before reading data, call QTcpSocket::bytesAvailable to determine that enough data is available. QTcpServer handles the connection of the client. It can listen to the connection request sent by the client through QTcpServer::listen(). Whenever there is a client connection, it will send a newConnection() signal. QTcpSocket can be used to read and send datagrams sent by the client.

2, Similarities and differences between two transport layer protocols Tcp\Udp

3, Small demo to realize Tcp client server communication

1, Server:

  • Create a new Qt Widgets Application as a tcp server. The server can only passively wait for a connection at any time. It can inherit from the Qwidget class. The ui is designed as follows:
  • Open the pro file and add a network programming module. The client also needs to make the following modifications:
  • Add tcp server M_ tcp server, tcp server socket m_tcpSocket monitors the connection of the client in the constructor. In the example, the server mainly monitors port 6666 on any ip address and adds the corresponding slot function for the newConnection signal when the client connects.
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTcpServer>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
private slots:
    void onNewConnect();    //Client new connection request processing
    void onSendBackMsg();   //Feedback information to the client for new connections
    void onReadMsg();       //The server reads the data sent by the client
private:
    Ui::Widget *ui;
    QTcpServer* m_tcpServer;    //tcp server
    QTcpSocket* m_tcpSocket;    //tcp socket
};
#endif // WIDGET_H
  • When the server receives the connection from the client, the server tcp feeds back the information to the client, and the data displayed by the client is displayed on the label:
#include "widget.h"
#include "ui_widget.h"
#include <QTcpSocket>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    m_tcpServer=new QTcpServer(this);
    //The server listens for requests from the client
    if(!m_tcpServer->listen(QHostAddress::AnyIPv4,6666)){
        qDebug()<<m_tcpServer->errorString();
        close();
    }
    connect(m_tcpServer,&QTcpServer::newConnection,this,&Widget::onNewConnect);
    connect(m_tcpServer,&QTcpServer::newConnection,this,&Widget::onSendBackMsg);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::onNewConnect()
{
    //Currently connected clients
    m_tcpSocket=m_tcpServer->nextPendingConnection();
    //Disconnect
    connect(m_tcpSocket,&QTcpSocket::disconnected,
            m_tcpSocket,&QTcpSocket::deleteLater);
    //When the socket has data, it will send readyRead signal
    connect(m_tcpSocket,&QTcpSocket::readyRead,
            this,&Widget::onReadMsg);
}
void Widget::onSendBackMsg()
{
    QString str="Hello, client!";
    m_tcpSocket->write(str.toUtf8());
    ui->label->setText("Feedback data succeeded!");

}

void Widget::onReadMsg()
{
    //The server displays the data sent by the client on the label
    QByteArray bt=m_tcpSocket->readAll();
    ui->readLabel->setText(bt);
}

2, Client

  • Like the server, create a new Qt Widgets Application project as a tcp client, inherit from the Qwidget class, and design the ui as follows:
  • Add client tcp, add network programming module network in pro file, and add click signals to connect and send buttons.
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTcpSocket>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
private slots:
    void onReadMessage();   //Process the data fed back by the server
    void onDisplayError(QAbstractSocket::SocketError e);    //Print error message
    void on_connectBtn_clicked();   //Click the connect button to respond to the slot function of the signal
    void on_sendBtn_clicked();  //Click the send button to respond to the slot function
private:
    Ui::Widget *ui;
    QTcpSocket* m_tcpSocket;    //tcp client
};
#endif // WIDGET_H

  • The constructor adds the responding slot function onReadMessage to the readyRead signal triggered when the server sends data, and sets the default ip address and port when the client connects. The onReadMessage slot function displays the data fed back by the server on the label, on_ sendBtn_ The clicked slot function sends the contents of the line edit box to the tcp server.
#include "widget.h"
#include "ui_widget.h"
#include <QAbstractSocket>
const int gTcpPort=6666;
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    m_tcpSocket=new QTcpSocket(this);
    //There is data in the socket for processing
    connect(m_tcpSocket,&QTcpSocket::readyRead,
            this,&Widget::onReadMessage);
    connect(m_tcpSocket,SIGNAL(QAbstractSocket::SocketError),
            this,SLOT(onDisplayError(QAbstractSocket::SocketError)));
    //Set the default host address and port number for client connection
    ui->hostLineEdit->setText("127.0.0.1");
    ui->portLineEdit->setText(QString::number(gTcpPort));
}

Widget::~Widget()
{
    delete ui;
}

void Widget::onReadMessage()
{
    QByteArray bt;
    bt.resize(m_tcpSocket->bytesAvailable());
    m_tcpSocket->read(bt.data(),bt.size());
    //Display the data fed back by the client on the label
    ui->recvLabel->setText(bt);
}

void Widget::onDisplayError(QAbstractSocket::SocketError e)
{
    qDebug()<<"SocketError:"<<e<<endl
           <<m_tcpSocket->errorString();
}

void Widget::on_connectBtn_clicked()
{
    m_tcpSocket->abort();
    //Connect server
    m_tcpSocket->connectToHost(ui->hostLineEdit->text(),
                               ui->portLineEdit->text().toInt());
}

void Widget::on_sendBtn_clicked()
{
    m_tcpSocket->write(ui->sendEdit->text().toUtf8());
    m_tcpSocket->flush();//Empty buffer
}

4, Operation results

  • Open the server first, and then run the client

  • The client adopts the default ip and port. The ip address here can also be changed to other. The port must be consistent with the listening port of the server. Click Connect:

  • Enter any content in the line edit box and click send:

ok, achieve your goal!

Keywords: Qt udp TCP/IP

Added by baudday on Mon, 20 Sep 2021 04:04:28 +0300