Qt中的网络通信
使用方式
需要在 .pro
文件中引入 network
QT += core gui network
一、TCP通信实现
TCP协议适用于需可靠传输的场景(如文件传输、数据库连接),其核心类为QTcpServer
和QTcpSocket
。
服务器端流程
// 1. 在server的头文件中引入QTcpServer
#ifndef SEVER_H
#define SEVER_H#include <QWidget>
#include <QTcpServer>
#include <QTcpSocket>namespace Ui {
class Sever;
}class Sever : public QWidget
{Q_OBJECTpublic:explicit Sever(QWidget *parent = nullptr);~Sever();private:Ui::Sever *ui;QTcpServer *server;QTcpSocket *severSocket;
};#endif // SEVER_H// 2. 在cpp文件里面才创建server服务器
#include "sever.h"
#include "ui_sever.h"Sever::Sever(QWidget *parent) :QWidget(parent),ui(new Ui::Sever)
{ui->setupUi(this);// 2.1. 创建服务器,并监听一个固定的端口号this->server = new QTcpServer(this);// listen(参数1, 参数2)// 参数1:匹配ip地址的模式,更多模式查找listen// 参数2:匹配ip地址的端口号this->server->listen(QHostAddress::Any, 8888);// 2.2. 服务器监听是否有客户端连接,一旦有客户端连接,就会触发 QTcpServer::newConnection 信号connect(this->server,&QTcpServer::newConnection,[this](){// 获取连接客户端ip地址和端口号,通过nextPendingConnection()获取客户端的socket信息this->serverSocket = this->server->nextPendingConnection();// 通过peer一系列方法QString ip = this->serverSocket->peerAddress().toString();uint16 port = this->serverSocke->peerPort();// 2.3 服务器向客户端发送数据,一旦客户端有数据发送过来,就会触发 QTcpSocket::readyRead 信号connect(this->serverSocket,&QTcpSocket::readyRead,[this](){// 获取客户端发送的内容,通过readAll()函数获取发送的数据,返回值类型是QByteArrayQByteArray buffer = this->serverSocket->readAll();});});// 2.4 断开与客户端的连接通过disconnectFromHost()函数断开连接this->clientSocket->disconnectFromHost();
}Server::~Server()
{delete ui;
}
客户端流程
// 1. 在client的头文件中引入QTcpSocket
#ifndef CLIENT_H
#define CLIENT_H#include <QWidget>
#include <QTcpSocket>namespace Ui {
class Client;
}class Client : public QWidget
{Q_OBJECTpublic:explicit Client(QWidget *parent = nullptr);~Client();private:Ui::Client *ui;QTcpSocket *clientSocket;
};#endif // CLIENT_H// 2. 在cpp文件中实现TcpSocket
#include "client.h"
#include "ui_client.h"Client::Client(QWidget *parent) :QWidget(parent),ui(new Ui::Client)
{ui->setupUi(this);// 2.1 创建客户端this->clientSocket = new QTcpSocket;// 2.1 客户端连接服务端// 使用connectToHost(参数1, 参数2)来连接服务端// 参数1:QString的ip地址// 参数2:quint16的port端口号this->clientSocket->connectToHost(ip,port);// 2.2 客户端向客户端发送消息,将数据写入clientSocket中,通过write()函数,参数类型是QByteArraythis->clientSocket->write(data);// 2.3 客户端接收服务端发送的数据,就会触发 QTcpSocket::readyRead 信号connect(this->clientSocket,&QTcpSocket::readyRead,[this](){// 获取服务端发送的内容,通过readAll()函数获取发送的数据,返回值类型是QByteArrayQByteArray buffer = this->clientSocket->readAll();});// 2.4 断开与服务端的连接通过disconnectFromHost()函数断开连接this->clientSocket->disconnectFromHost();
}
二、UDP通信实现
UDP协议适用于实时性高、容忍丢包的场景(如视频流、在线游戏),核心类为QUdpSocket。
// 在使用之前需要在工程文件中引入 network
// 1 在c1头文件中引入QUdpSocket
#ifndef C1_H
#define C1_H#include <QWidget>
#include <QUdpSocket>namespace Ui {
class C1;
}class C1 : public QWidget
{Q_OBJECTpublic:explicit C1(QWidget *parent = nullptr);~C1();private:Ui::C1 *ui;QUdpSocket *c1Socket;
};#endif // C1_H// 2. 在cpp文件里面创建c1Socket对象
#include "c1.h"
#include "ui_c1.h"C1::C1(QWidget *parent) :QWidget(parent),ui(new Ui::C1)
{ui->setupUi(this);// 2.1 创建c1Socket对象并通过bind()函数绑定监听的端口号this->c1Socket = new QUdpSocket(this);this->c1Socket->bind(8888);// 2.2 向其他客户端发送消息,将数据写入到socket中,通过writeDatagram()函数// 函数有三个参数,参数一:发送的数据类型为QByteArray;参数二:发送到ip的地址类型为QHostAddress;参数三:发送到ip的port端口号类型为quint16this->c1Socket->writeDatagram(data,ip,port);// 2.3 接收其他客户端发送的消息,通过 QUdpSocket::readyRead 信号connect(this->c1Socket,&QUdpSocket::readyRead,[this](){// 获取发送的数据,通过readDatagram()函数获取数据,并将其存储到char*中// 函数参数有四个,参数一:存储发送的数据的字符指针;参数二:每次读取的长度;参数三:发送数据的ip地址;参数四:发送数据ip地址的port端口号char buffer[1024] = {0};QHostAddress ip;quint16 port;this->c1Socket->readDatagram(buffer,1024,&ip,&port);});}C1::~C1()
{delete ui;
}
三、TCP与UDP核心对比
特性 | TCP | UDP |
---|---|---|
连接方式 | 面向连接(三次握手) | 无连接 |
可靠性 | 可靠(重传、流量控制) | 不可靠(可能丢包、乱序) |
延迟 | 较高(需建立连接) | 低(直接发送) |
适用场景 | 文件传输、Web请求 | 实时音视频、游戏 |
Qt类 | QTcpServer /QTcpSocket | QUdpSocket |
也可以借鉴其他博主的风陵南的QT 网络编程QTcpServer服务端