Qt implements TCP communication and UDP communication

Qt implements TCP communication and UDP communication

1, TCP communication

The following classes are mainly used to implement TCP communication in QT: QTcpServer, QTcpSocket, QHostAddress, etc.;

  • Use QTcpServer to create a TCP server. When a new connection is established, add the newly established socket to the list in order to send data, while listening on the specified IP address and port, and when there is a new client connection when processing;
  • Use QTcpSocket to create a TCP client, connect to the server and send data;

Sample code:

(1) Create two header files (TcpServer.h and TcpClient.h):

TcpServer.h

#ifndef TCPSERVER_H
#define TCPSERVER_H

#include <QObject>
#include <QTcpServer>
#include <QTcpSocket>

class TcpServer : public QObject
{
    
    
    Q_OBJECT
public:
    explicit TcpServer(QObject *parent = nullptr);

signals:

public slots:
    void startServer();
    void newClientConnection();
    void readData();
    void clientDisconnected();

private:
    QTcpServer *tcpServer;
    QList<QTcpSocket *> clients;
};

#endif // TCPSERVER_H

TcpClient.h

#ifndef TCPCLIENT_H
#define TCPCLIENT_H

#include <QObject>
#include <QTcpSocket>

class TcpClient : public QObject
{
    
    
    Q_OBJECT
public:
    explicit TcpClient(QObject *parent = nullptr);

public slots:
    void onConnected();
    void onDisconnected();
    void onError(QAbstractSocket::SocketError error);
    void onReadyRead();
    void connectToServer(QString ipAddress, int port);
    void sendData(QByteArray data);

private:
    QTcpSocket *socket;
};

#endif // TCPCLIENT_H

(2) Create two source files (TcpServer.cpp and TcpClient.cpp):

TcpServer.cpp

#include "tcpserver.h"
#include <QDebug>

TcpServer::TcpServer(QObject *parent) : QObject(parent)
{
    
    
}

void TcpServer::startServer()
{
    
    
    tcpServer = new QTcpServer(this);
    connect(tcpServer, SIGNAL(newConnection()), this, SLOT(newClientConnection()));

    if (!tcpServer->listen(QHostAddress::Any, 1234))
    {
    
    
        qDebug() << "Unable to start the server: " << tcpServer->errorString();
        return;
    }
    qDebug() << "Listening on " << QHostAddress::Any << ":" << "1234";
}

void TcpServer::newClientConnection()
{
    
    
    while (tcpServer->hasPendingConnections())
    {
    
    
        QTcpSocket *client = tcpServer->nextPendingConnection();
        clients.push_back(client);
        QObject::connect(client, SIGNAL(readyRead()), this, SLOT(readData()));
        QObject::connect(client, SIGNAL(disconnected()), this, SLOT(clientDisconnected()));
    }
}

void TcpServer::readData()
{
    
    
    QTcpSocket *sender = static_cast<QTcpSocket*>(QObject::sender());
    QByteArray data = sender->readAll();
    qDebug() << "Received: " << data;
}

void TcpServer::clientDisconnected()
{
    
    
    QTcpSocket *sender = static_cast<QTcpSocket*>(QObject::sender());
    clients.removeOne(sender);
    sender->deleteLater();
}

TcpClient.cpp

#include "tcpclient.h"
#include <QDebug>

TcpClient::TcpClient(QObject *parent) : QObject(parent)
{
    
    
}

void TcpClient::connectToServer(QString ipAddress, int port)
{
    
    
    socket = new QTcpSocket(this);
    connect(socket, SIGNAL(connected()), this, SLOT(onConnected()));
    connect(socket, SIGNAL(disconnected()), this, SLOT(onDisconnected()));
    connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(onError(QAbstractSocket::SocketError)));
    connect(socket, SIGNAL(readyRead()), this, SLOT(onReadyRead()));

    socket->connectToHost(ipAddress, port);
}

void TcpClient::sendData(QByteArray data)
{
    
    
    if (socket && socket->state() == QAbstractSocket::ConnectedState)
        socket->write(data);
}

void TcpClient::onConnected()
{
    
    
    qDebug() << "Connected!";
}

void TcpClient::onDisconnected()
{
    
    
    qDebug() << "Disconnected!";
}

void TcpClient::onError(QAbstractSocket::SocketError error)
{
    
    
    qDebug() << "Error: " << socket->errorString();
}

void TcpClient::onReadyRead()
{
    
    
    qDebug() << "Received: " << socket->readAll();
}

(3) The TCP client communicates with the TCP server, open main.cpp, add header files and create TcpServer objects and TcpClient objects:

main.cpp

#include <QCoreApplication>
#include "tcpserver.h"
#include "tcpclient.h"

int main(int argc, char *argv[])
{
    
    
    QCoreApplication a(argc, argv);

    //创建服务器对象
    TcpServer server;
    server.startServer();

    //创建客户端对象
    TcpClient client;
    client.connectToServer("127.0.0.1", 1234);

    //发送数据
    client.sendData("Hello from client!");

    return a.exec();
}

2, UDP communication

The following classes are mainly used to realize UDP communication in QT: QUdpSocket, QHostAddress, etc.;

  • UdpServer is the server side, used to listen to the message sent by the client and reply the same message;
  • UdpClient is a client that sends a message to the server and waits for a reply from the server;

Sample code:

(1) Create two header files (UdpServer.h and UdpClient.h):

UdpServer.h

UdpServer inherits from QObject, this class contains private member variables QUdpSocket *udpSocket, the start() function is used to start the server;

#ifndef UDPSERVER_H
#define UDPSERVER_H

# 这两个头文件分别用于QObject基类和QUdpSocket类,前者提供Qt对象模型所需的大量工具和服务,后者用于UDP套接字支持
#include <QObject>
#include <QUdpSocket>

class UdpServer : public QObject
{
    
    
    Q_OBJECT
public:
    explicit UdpServer(QObject *parent = nullptr);
    void start();

signals:

private:
    QUdpSocket *udpSocket;
};

#endif // UDPSERVER_H

UdpClient.h

UdpClient also inherits from QObject, which contains a QUdpSocket pointer udpSocket and a send() function for sending messages to the server;

#ifndef UDPCLIENT_H
#define UDPCLIENT_H

#include <QObject>
#include <QUdpSocket>

class UdpClient : public QObject
{
    
    
    Q_OBJECT
public:
    explicit UdpClient(QObject *parent = nullptr);
    void send(const QString &message);

signals:

private:
    QUdpSocket *udpSocket;
};

#endif // UDPCLIENT_H

(2) Create two source files (UdpServer.cpp and UdpClient.cpp):

UdpServer.cpp

In the implementation file of UdpServer, a QUdpSocket object udpSocket is first created in the constructor, which is used for communication, and the start() function is used to start the server, including binding ports and establishing connections for receiving data:

  • The bind() function is used to bind a UDP socket to an IP address and port in order to start listening for incoming messages;
  • The readyRead signal is a signal of the QUdpSocket class. Here, the connect() function is used to connect it to another function, which will be executed every time data is received;
#include "UdpServer.h"
#include <QDebug>

UdpServer::UdpServer(QObject *parent) : QObject(parent)
{
    
    
    udpSocket = new QUdpSocket(this);
}

void UdpServer::start()
{
    
    
    quint16 port = 1234;

    if (udpSocket->bind(QHostAddress::AnyIPv4, port))
    {
    
    
        qDebug() << "UDP server is listening on port" << port;
    }
    else
    {
    
    
        qDebug() << "Failed to bind the UDP server to port" << port;
    }

    connect(udpSocket, &QUdpSocket::readyRead, this, [this]()
    {
    
    
        while (udpSocket->hasPendingDatagrams())
        {
    
    
            QByteArray datagram;
            datagram.resize(udpSocket->pendingDatagramSize());
            udpSocket->readDatagram(datagram.data(), datagram.size());

            qDebug() << "Received from client:" << datagram;
        }
    });
}

UdpClient.cpp

In the implementation file of UdpClient, a QUdpSocket object udpSocket is also created in the constructor for communication, and the send() function is used to send messages to the server:

  • The writeDatagram() function is used to send the datagram specified by datagram to the target address and port;
  • The qDebug() function is used to output log information and record the messages sent to the server;
#include "UdpClient.h"
#include <QDebug>

UdpClient::UdpClient(QObject *parent) : QObject(parent)
{
    
    
    udpSocket = new QUdpSocket(this);
}

void UdpClient::send(const QString &message)
{
    
    
    QByteArray datagram = message.toUtf8();

    quint16 port = 1234;
    QHostAddress address("127.0.0.1");

    udpSocket->writeDatagram(datagram, address, port);

    qDebug() << "Sent to server:" << message;
}

(3) UDP client communicates with UDP server, open main.cpp, add header file and create UdpServer object and UdpClient object:

main.cpp

The main function is to start UdpServer and UdpClient, and send a message to the server:

  • udpServer and udpClient are instances used to run these two objects;
  • The send() function sends a message, which is received by the server and replies with the same message;
  • a.exec() function starts the Qt event loop until the program exits;
#include <QCoreApplication>
#include "UdpServer.h"
#include "UdpClient.h"

int main(int argc, char *argv[])
{
    
    
    QCoreApplication a(argc, argv);

    UdpServer udpServer;
    udpServer.start();

    UdpClient udpClient;
    udpClient.send("Hello from client!");

    return a.exec();
}

Run the program in Qt Creator, you can see the following output:

UDP server is listening on port 1234
Sent to server: "Hello from client!"
Received from client: "Hello from client!"

This indicates that the server successfully received the message from the client

Guess you like

Origin blog.csdn.net/qq_33867131/article/details/130323845