Realization of TCP communication based on QT (TCPServer and TCPClient)

Article directory

    • 1. Software introduction
      • 1.1 TCPServer server interface
      • 1.2 TCPClient client interface
      • 1.3 The server and client establish a connection and communicate with each other
    • Two, QT implements TCPServer and TCPClient
      • 2.1 TCPClient client
      • 2.1 TCPServer server
    • 3. Code sharing

Recently, because of the need to use the test
TCPServer (TCP server) and
TCPClient (TCP client) is used to send and receive communication and data, so the TCP server and TCP client are written with QT. This article shares the following development of TCPServer and TCP based on QT experience with TCPClient,
The source code is included in the article, and the source code file of the project is included at the end of the article.

1. Software introduction

TCPServer can bind an ip address and listen to a port. When TCPServer is bound and listening, you can use TCPClient to connect to the ip address and port bound to the server. After the connection is successful, you can communicate. The following first demonstrates the following server and client interfaces and communication processes.

1.1 TCPServer server interface

  • In the server interface, the “Start Listening” button can be clicked after setting the “Listening Address” and “Listening Port” to start listening to this ip address and port. When a TCPClient client requests a connection to this ip address and port The connection is made, and communication begins.
  • “Stop listening” can stop listening to the ip address and port number.
  • The “Clear Text Box” button can clear the message record, which is convenient for continuous information reading.
  • The “Exit” button closes the software.
  • “Send message” can send the content that has been entered.

1.2 TCPClient client interface

  • In the interface of the client, the “connect” button can be clicked after setting the “connection address” and “port” to start requesting connection to this ip address and port, when there is a TCPServer server listening to this ip address and port A connection can be made and communication can then begin.
  • “Disconnect” can mean disconnecting the established connection between the server and the client.
  • The “Clear Text Box” button can clear the message record, which is convenient for continuous information reading.
  • The “Send Message” and “Clear” buttons send and clear the entered content respectively.
  • The “Exit” button closes the software.

1.3 Server and client establish connection and communicate demonstration

  • First, on the server side, we bind ip: 192.168.31.222, port: 1200, and then click the “Start Listening” button, then the server side starts to wait for the client side to request to establish a connection.
  • Next, we use the client, set the connection address and port number to the ip: 192.168.31.222, port: 1200 bound to the server, and then click the “Connect” button, you can see that the connection between the two parties is successful, and the software shows that the connection is successfully established Prompt information.
  • The two parties can start communication after the connection is successfully established. We first click “Clear Text Box” to clear the prompt information, and then use the TCPServer server to send a message “Hello, I’m TCPServer~”, and you can see that the client has successfully received the message from the server. For the information sent, the content after [in] is the information received by the local end, and the content after [out] is the information sent by the local end.
  • Next, we use the TCPClient client to send a message “Hi, I’m TCPClient!” to the server, and we can see that the server has successfully received the message.

2. QT implements TCPServer and TCPClient

If we want to implement TCP communication in QT, we need to add the following line of code to the .pro file:

QT + = network

2.1 TCPClient client

  • First of all, we should include the following three header files to support us calling internal communication functions:
#include <QTcpSocket>
#include <QHostAddress>
#include <QHostInfo>
  • Create a QTcpSocket socket object
tcpClient = new QTcpSocket(this);
  • Use the tcpClient object to connect to the server
tcpClient ->connectToHost(IP, port);
  • Then we use the write() function to send data to the server
tcpClient->write(data);
  • When new data arrives in the tcpClient receiving buffer, the readRead() signal will be issued, so add a slot function to the signal to read data
connect(tcpClient,SIGNAL(readyRead()),this,SLOT(onSocketReadyRead()));

void MainWindow::onSocketReadyRead()
{<!-- -->//readyRead() signal slot function
    while(tcpClient->canReadLine())
        ui->plainTextEdit->appendPlainText("[in] " + tcpClient->readLine());
}
  • Need to disconnect after we’re done communicating
void MainWindow::on_actDisconnect_triggered()
{<!-- -->//Disconnect from the server
    if (tcpClient->state()==QAbstractSocket::ConnectedState)
        tcpClient->disconnectFromHost();
}

The code for TCPClient is given below

  • main.cpp
#include "mainwindow.h"
#include <QApplication>
#include <QFile>

int main(int argc, char *argv[])
{<!-- -->
    QApplication a(argc, argv);
    MainWindow w;
    w.resize(700,900);
    w. show();

    return a.exec();
}

  • mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTcpSocket>
#include <QLabel>

namespace Ui {<!-- -->
class MainWindow;
}

class MainWindow : public QMainWindow
{<!-- -->
    Q_OBJECT
private:
    QTcpSocket *tcpClient; //socket
    QLabel *LabSocketState; //Status bar display label

    QString getLocalIP();//Get the local IP address
protected:
    void closeEvent(QCloseEvent *event);
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
//custom slot function
    void onConnected();
    void onDisconnected();
    void onSocketStateChange(QAbstractSocket::SocketState socketState);
    void onSocketReadyRead();//Read the incoming data from the socket

    void on_actConnect_triggered();
    void on_actDisconnect_triggered();
    void on_actClear_triggered();
    void on_btnSend_clicked();
    void on_btnClear_clicked();
    void on_actionTimeCurrent_triggered();

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

  • mainwindow.cpp
#pragma execution_character_set("utf-8")
#include "mainwindow.h"
#include "ui_mainwindow.h"

#include 
#include 
#include 

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    tcpClient = new QTcpSocket(this); //create socket variable

    LabSocketState = new QLabel("Socket state:");//Status bar label
    LabSocketState->setMinimumWidth(250);
    ui->statusBar->addWidget(LabSocketState);

    QString localIP=getLocalIP();//Local IP
    this->setWindowTitle("TCP client");
    ui->comboServer->addItem(localIP);

    setFocusPolicy(Qt::StrongFocus);
    installEventFilter(this);

    connect(tcpClient,SIGNAL(connected()),this,SLOT(onConnected()));
    connect(tcpClient,SIGNAL(disconnected()),this,SLOT(onDisconnected()));

    connect(tcpClient,SIGNAL(stateChanged(QAbstractSocket::SocketState)),this,SLOT(onSocketStateChange(QAbstractSocket::SocketState)));
    connect(tcpClient,SIGNAL(readyRead()),this,SLOT(onSocketReadyRead()));
}

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

void MainWindow::onConnected()
{ //connected() signal slot function
    ui->plainTextEdit->appendPlainText("**connected to the server");
    ui->plainTextEdit->appendPlainText("**peer address:" + tcpClient->peerAddress().toString());
    ui->plainTextEdit->appendPlainText("**peer port:" + QString::number(tcpClient->peerPort()));
    ui->actConnect->setEnabled(false);
    ui->actDisconnect->setEnabled(true);
}

QString MainWindow::getLocalIP()
{
    QString hostName = QHostInfo::localHostName();//local host name
    QHostInfo hostInfo = QHostInfo::fromName(hostName);
    QString localIP = "";

    QList addList=hostInfo. addresses();

    if (!addList.isEmpty())
    for (int i=0;i
        QHostAddress aHost = addList.at(i);
        if (QAbstractSocket::IPv4Protocol == aHost. protocol())
        {
            localIP=aHost.toString();
            break;
        }
    }
    return localIP;
}
void MainWindow::closeEvent(QCloseEvent *event)
{
    if (tcpClient->state() == QAbstractSocket::ConnectedState)
        tcpClient->disconnectFromHost();
    event->accept();
}

void MainWindow::onDisconnected()
{//disConnected() signal slot function
    ui->plainTextEdit->appendPlainText("**The connection with the server has been disconnected");
    ui->actConnect->setEnabled(true);
    ui->actDisconnect->setEnabled(false);
}

void MainWindow::onSocketReadyRead()
{//readyRead() signal slot function
    while(tcpClient->canReadLine())
        ui->plainTextEdit->appendPlainText("[in] " + tcpClient->readLine());
}

void MainWindow::onSocketStateChange(QAbstractSocket::SocketState socketState)
{//stateChange() signal slot function
    switch(socketState)
    {
    case QAbstractSocket::UnconnectedState:
        LabSocketState->setText("scoket state: UnconnectedState");
        break;
    case QAbstractSocket::HostLookupState:
        LabSocketState->setText("scoket state: HostLookupState");
        break;
    case QAbstractSocket::ConnectingState:
        LabSocketState->setText("scoket state: ConnectingState");
        break;

    case QAbstractSocket::ConnectedState:
        LabSocketState->setText("scoket state: ConnectedState");
        break;

    case QAbstractSocket::BoundState:
        LabSocketState->setText("scoket state: BoundState");
        break;

    case QAbstractSocket::ClosingState:
        LabSocketState->setText("scoket state: ClosingState");
        break;

    case QAbstractSocket::ListeningState:
        LabSocketState->setText("scoket state: ListeningState");
    }
}

void MainWindow::on_actConnect_triggered()
{//Connect to the server
    QString addr=ui->comboServer->currentText();
    quint16 port=ui->spinPort->value();
    tcpClient->connectToHost(addr,port);
}

void MainWindow::on_actDisconnect_triggered()
{<!-- -->//Disconnect from the server
    if (tcpClient->state()==QAbstractSocket::ConnectedState)
        tcpClient->disconnectFromHost();
}

void MainWindow::on_actClear_triggered()
{
    ui->plainTextEdit->clear();
}

void MainWindow::on_btnSend_clicked()
{//Send data

    QString msg=ui->editMsg->toPlainText();
    ui->plainTextEdit->appendPlainText("[out] " + msg);

    ui->editMsg->setFocus();

    QByteArray str = msg.toLatin1();
    str.append("\r\
");
    tcpClient->write(str);
}

void MainWindow::on_btnClear_clicked()
{
    ui->editMsg->clear();
}

void MainWindow::on_actionTimeCurrent_triggered()
{
    QString msg=QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz");
    ui->plainTextEdit->appendPlainText( + " [out] " + msg);

    ui->editMsg->setFocus();

    QByteArray str = msg.toLatin1();
    str.append("\r\
\r\
");
    tcpClient->write(str);
}

  • ui interface

2.1 TCPServer server

  • First we need to include the following header files to provide the functions we need to call:
#include <QTcpServer>
#include <QtNetwork>
  • Then create a TCPServer object
tcpServer=new QTcpServer(this);
  • Bind ip and monitor the port function, so that the client can access the server through this port
tcpServer->listen(addr,port);
  • When tcpServer is accessed by tcpClient, it will issue a newConnection() signal, so add a slot function for this signal, and use a QTcpSocket object to accept client access
connect(tcpServer,SIGNAL(newConnection()),this,SLOT(onNewConnection()));

void MainWindow::onNewConnection()
{<!-- -->
    tcpSocket = tcpServer->nextPendingConnection(); //create socket

    connect(tcpSocket, SIGNAL(connected()), this, SLOT(onClientConnected()));
    onClientConnected();
    connect(tcpSocket, SIGNAL(disconnected()), this, SLOT(onClientDisconnected()));
    connect(tcpSocket,SIGNAL(stateChanged(QAbstractSocket::SocketState)),this,SLOT(onSocketStateChange(QAbstractSocket::SocketState)));
    onSocketStateChange(tcpSocket->state());
    connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(onSocketReadyRead()));
}
  • Use the write() function of tcpSocket to send data to the client
tcpSocket->write(data);
  • When new data arrives in the tcpSocket receiving buffer, the readRead() signal will be issued, so add a slot function to the signal to read data
connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(onSocketReadyRead()));

void MainWindow::onSocketReadyRead()
{<!-- -->
    while(tcpSocket->canReadLine()){<!-- -->
        ui->plainTextEdit->appendPlainText("[in] " + tcpSocket->readLine());
    }
}
  • stop listening
void MainWindow::on_actStop_triggered()
{<!-- -->
    if (tcpServer->isListening()) //tcpServer is listening
    {<!-- -->
        tcpServer->close();//stop listening
        ui->actStart->setEnabled(true);
        ui->actStop->setEnabled(false);
        LabListen->setText("Listening Status: Stopped Listening");
    }
}

The code for TCPServer is given below

  • main.cpp
#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{<!-- -->
    QApplication a(argc, argv);
    MainWindow w;
    w.resize(600,700);
    w. show();

    return a.exec();
}

  • mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTcpServer>
#include <QLabel>

namespace Ui {<!-- -->
class MainWindow;
}

class MainWindow : public QMainWindow
{<!-- -->
    Q_OBJECT

protected:
    void closeEvent(QCloseEvent *event);//Stop listening when the window is closed

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    void onNewConnection();//QTcpServer's newConnection() signal
    void onSocketStateChange(QAbstractSocket::SocketState socketState);//The bottom socket state changes
    void onClientConnected(); //When the client connects
    void onClientDisconnected();//When the client disconnects
    void onSocketReadyRead();//Read the incoming data from the socket

    void on_actStart_triggered();//Start listening
    void on_actStop_triggered();//stop listening
    void on_actClear_triggered();//clear
    void on_btnSend_clicked();//send message
    void on_actHostInfo_triggered();//Get the local address

private:
    Ui::MainWindow *ui;
    QLabel *LabListen;//Status bar label
    QLabel *LabSocketState;//Status bar label
    QTcpServer *tcpServer; //TCP server
    QTcpSocket *tcpSocket;//Socket for TCP communication
    QString getLocalIP();//Get the local IP address
};

#endif // MAINWINDOW_H

  • mainwindow.cpp
#pragma execution_character_set("utf-8")
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include 

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    LabListen=new QLabel("Listening status:");
    LabListen->setMinimumWidth(150);
    ui->statusBar->addWidget(LabListen);

    LabSocketState=new QLabel("Socket state:");
    LabSocketState->setMinimumWidth(200);
    ui->statusBar->addWidget(LabSocketState);

    QString localIP=getLocalIP();//Local IP
    this->setWindowTitle(this->windowTitle() + "----Local IP: " + localIP);
    ui->comboIP->addItem(localIP);

    tcpServer=new QTcpServer(this);
    connect(tcpServer,SIGNAL(newConnection()),this,SLOT(onNewConnection()));
}

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

QString MainWindow::getLocalIP()
{
    QString hostName=QHostInfo::localHostName();//local host name
    QHostInfo hostInfo=QHostInfo::fromName(hostName);
    QString localIP="";

    QList addList=hostInfo. addresses();

    if (!addList.isEmpty())
    for (int i=0;i
        QHostAddress aHost = addList.at(i);
        if (QAbstractSocket::IPv4Protocol==aHost.protocol())
        {
            localIP=aHost.toString();
            break;
        }
    }
    return localIP;
}

void MainWindow::closeEvent(QCloseEvent *event)
{
    if (tcpServer->isListening())
        tcpServer->close();//stop network monitoring
    event->accept();
}

void MainWindow::onNewConnection()
{
    tcpSocket = tcpServer->nextPendingConnection(); //create socket

    connect(tcpSocket, SIGNAL(connected()), this, SLOT(onClientConnected()));
    onClientConnected();
    connect(tcpSocket, SIGNAL(disconnected()), this, SLOT(onClientDisconnected()));
    connect(tcpSocket,SIGNAL(stateChanged(QAbstractSocket::SocketState)),this,SLOT(onSocketStateChange(QAbstractSocket::SocketState)));
    onSocketStateChange(tcpSocket->state());
    connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(onSocketReadyRead()));
}

void MainWindow::onSocketStateChange(QAbstractSocket::SocketState socketState)
{
    qDebug()<<"Come here";
    switch(socketState)
    {
    case QAbstractSocket::UnconnectedState:
        LabSocketState->setText("scoket state: UnconnectedState");
        break;
    case QAbstractSocket::HostLookupState:
        LabSocketState->setText("scoket state: HostLookupState");
        break;
    case QAbstractSocket::ConnectingState:
        LabSocketState->setText("scoket state: ConnectingState");
        break;
    case QAbstractSocket::ConnectedState:
        LabSocketState->setText("scoket state: ConnectedState");
        break;
    case QAbstractSocket::BoundState:
        LabSocketState->setText("scoket state: BoundState");
        break;
    case QAbstractSocket::ClosingState:
        LabSocketState->setText("scoket state: ClosingState");
        break;
    case QAbstractSocket::ListeningState:
        LabSocketState->setText("scoket state: ListeningState");
    }
}

void MainWindow::onClientConnected()
{
    ui->plainTextEdit->appendPlainText("**client socket connected");
    ui->plainTextEdit->appendPlainText("**peer address:" + tcpSocket->peerAddress().toString());
    ui->plainTextEdit->appendPlainText("**peer port:" + QString::number(tcpSocket->peerPort()));
}

void MainWindow::onClientDisconnected()
{
    ui->plainTextEdit->appendPlainText("**client socket disconnected");
    tcpSocket->deleteLater();
    // deleteLater();//QObject::deleteLater();
}

void MainWindow::onSocketReadyRead()
{
    while(tcpSocket->canReadLine()){
        ui->plainTextEdit->appendPlainText("[in] " + tcpSocket->readLine());
    }
}

void MainWindow::on_actStart_triggered()
{
    QString IP=ui->comboIP->currentText();//IP address
    quint16 port=ui->spinPort->value();//port
    QHostAddress addr(IP);
    tcpServer->listen(addr,port);//
    ui->plainTextEdit->appendPlainText("**Start listening...");
    ui->plainTextEdit->appendPlainText("**server address: " + tcpServer->serverAddress().toString());
    ui->plainTextEdit->appendPlainText("**Server port: " + QString::number(tcpServer->serverPort()));

    ui->actStart->setEnabled(false);
    ui->actStop->setEnabled(true);

    LabListen->setText("Listening Status: Listening");
}

void MainWindow::on_actStop_triggered()
{<!-- -->
    if (tcpServer->isListening()) //tcpServer is listening
    {<!-- -->
        tcpServer->close();//stop listening
        ui->actStart->setEnabled(true);
        ui->actStop->setEnabled(false);
        LabListen->setText("Listening Status: Stopped Listening");
    }
}

void MainWindow::on_actClear_triggered()
{
    ui->plainTextEdit->clear();
}

void MainWindow::on_btnSend_clicked()
{
    QString msg=ui->editMsg->text();
    ui->plainTextEdit->appendPlainText("[out] " + msg);
    ui->editMsg->clear();
    ui->editMsg->setFocus();

    QByteArray str=msg.toUtf8();
    str.append("\r\
");//Add a newline
    tcpSocket->write(str);
}

void MainWindow::on_actHostInfo_triggered()
{
    QString hostName=QHostInfo::localHostName();//local host name
    ui->plainTextEdit->appendPlainText("Local host name: " + hostName + "\
");
    QHostInfo hostInfo=QHostInfo::fromName(hostName);

    QList addList=hostInfo.addresses();//
    if (!addList.isEmpty())
    for (int i=0;i
        QHostAddress aHost = addList.at(i);
        if (QAbstractSocket::IPv4Protocol==aHost.protocol())
        {
            QString IP=aHost.toString();
            ui->plainTextEdit->appendPlainText("Local IP address: " + aHost.toString());
            if (ui->comboIP->findText(IP)<0)
                ui->comboIP->addItem(IP);
        }
    }
}

  • ui interface

3. Code sharing

In the future, a UDP communication tool based on QT will be written, and the code is given below.

  • Baidu Netdisk
    TCPClient extraction code 1234
    TCPServer extraction code 1234
  • CSDN resources
    TCPServer
    TCPClient