QT-网络编程

发布时间 2023-08-25 20:05:53作者: 不会笑的孩子

说明

当涉及 Qt 网络编程时,通常会使用 Qt 提供的网络模块,其中最常用的是 QTcpSocket 和 QTcpServer 类

QTcpSocket

QTcpSocket 是 Qt 网络模块中的一个类,用于实现 TCP 客户端的网络通信。它提供了一个接口,允许你连接到远程主机并在网络上发送和接收数据

1.构造函数

QTcpSocket(QObject *parent = nullptr);

你可以通过这个构造函数创建一个 QTcpSocket 实例。可以通过 parent 参数设置父对象,用于管理对象的内存释放。

2.连接

void connectToHost(const QString &hostName, quint16 port, OpenMode openMode = ReadWrite);
void connectToHost(const QHostAddress &address, quint16 port, OpenMode openMode = ReadWrite);

3. 信号和槽:

QTcpSocket 提供了多个信号和槽,用于处理连接状态、数据接收等。常用的信号包括 connected()(连接成功时触发)、disconnected()(断开连接时触发)、readyRead()(有数据可读时触发)等。

4.数据传输

qint64 write(const char *data, qint64 maxSize);
qint64 write(const QByteArray &byteArray);
qint64 read(char *data, qint64 maxSize);
QByteArray read(qint64 maxSize);

通过这些函数,你可以向套接字写入数据或从套接字读取数据。write() 将数据发送到连接的远程主机,read() 从连接中读取数据。

5. 关闭连接:

void close();
void disconnectFromHost();

close() 函数用于关闭套接字。disconnectFromHost() 函数用于断开与远程主机的连接。

6. 异常处理:

QTcpSocket 可以通过检查状态和错误代码来处理连接和数据传输中的异常情况。例如,可以使用 state() 函数检查连接状态,使用 error() 函数获取最后一次出现的错误。

QTcpServer

QTcpServer 是 Qt 网络模块中的一个类,用于创建 TCP 服务器以侦听连接请求,并为每个连接创建相应的 QTcpSocket 实例,以便进行数据交换。

1.构造函数

QTcpServer(QObject *parent = nullptr);

通过这个构造函数可以创建一个 QTcpServer 实例。parent 参数用于设置父对象,以便在内存管理方面进行管理。

2.开始监听

bool listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0);

调用这个函数会使服务器开始监听来自特定 IP 地址和端口的连接请求。你可以通过 address 参数设置要监听的 IP 地址,使用 QHostAddress::Any 表示监听所有可用的网络接口。port 参数指定监听的端口号,使用 0 表示自动选择一个空闲端口。

3.信号和槽

QTcpServer 提供了多个信号和槽,用于处理新连接的到来、连接状态等。常用的信号包括 newConnection()(当有新的连接请求时触发)和 acceptError(QAbstractSocket::SocketError socketError)(当出现错误时触发)

4.处理连接:

QTcpSocket *nextPendingConnection();

在 newConnection() 信号触发后,你可以调用这个函数来获取一个待处理的连接。它会返回一个指向 QTcpSocket 实例的指针,你可以通过这个实例与客户端进行数据交换。

5. 关闭服务器:

void close();

6.异常处理

QTcpServer 可以通过检查状态和错误代码来处理服务器运行中可能出现的异常情况。例如,可以使用 isListening() 函数检查服务器是否在监听状态,使用 serverError() 函数获取最后一次出现的错误

7.多线程

在一些情况下,需要为每个连接创建一个新的线程,以避免主线程被阻塞。可以将 QTcpServer 与多线程结合使用,以提高服务器的并发性能。

8.SSL 加密:

QTcpServer 可以与 Qt 的 SSL 模块结合使用,从而创建安全的加密连接。这在保护敏感数据的通信中很有用。

这个函数用于关闭服务器,停止监听连接请求。

客户端

#include <QtNetwork>
#include <QTcpSocket>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    
    QTcpSocket socket;
    socket.connectToHost("127.0.0.1", 12345);
    if (!socket.waitForConnected()) {
        qDebug() << "Connection failed!";
        return 1;
    }
    
    qDebug() << "Connected to server.";
    socket.write("Hello from client!");
    socket.flush();
    
    if (socket.waitForReadyRead()) {
        QByteArray response = socket.readAll();
        qDebug() << "Response from server: " << response;
    }
    
    socket.disconnectFromHost();
    
    return a.exec();
}

服务端

#include <QtNetwork>
#include <QTcpServer>
#include <QTcpSocket>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    
    QTcpServer server;
    if (!server.listen(QHostAddress::Any, 12345)) {
        qDebug() << "Server could not start!";
        return 1;
    }
    qDebug() << "Server started. Listening on port 12345...";
    
    QObject::connect(&server, &QTcpServer::newConnection, [&](){
        QTcpSocket *socket = server.nextPendingConnection();
        QObject::connect(socket, &QTcpSocket::readyRead, [&](){
            QByteArray data = socket->readAll();
            qDebug() << "Received: " << data;
            socket->write("Server received: " + data);
            socket->flush();
        });
    });
    
    return a.exec();
}
#include <QtNetwork>
#include <QTcpServer>
#include <QTcpSocket>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    
    QTcpServer server;
    if (!server.listen(QHostAddress::Any, 12345)) {
        qDebug() << "Server could not start!";
        return 1;
    }
    qDebug() << "Server started. Listening on port 12345...";
    
    QObject::connect(&server, &QTcpServer::newConnection, [&](){
        QTcpSocket *socket = server.nextPendingConnection();
        QObject::connect(socket, &QTcpSocket::readyRead, [&](){
            QByteArray data = socket->readAll();
            qDebug() << "Received: " << data;
            socket->write("Server received: " + data);
            socket->flush();
        });
    });
    
    return a.exec();
}