欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 创投人物 > 【QT】Qt网络

【QT】Qt网络

2025/5/31 21:27:19 来源:https://blog.csdn.net/s_little_monster/article/details/143465913  浏览:    关键词:【QT】Qt网络

在这里插入图片描述
个人主页~


Qt系统相关

  • 一、Qt网络
    • 1、UDP Socket
      • (1)核心API
        • QNetworkDatagram
      • (2)回显服务器
        • widget.cpp
      • (3)回显客户端
        • widget.cpp
    • 2、TCP Socket
      • (1)核心API
        • QTcpServer
        • QTcpSocket
      • (2)回显服务器
      • (3)回显客户端
    • 3、HTTP Client
        • QNetworkAccessManager
        • QNetworkRequest
        • QNetworkReply

一、Qt网络

在这里插入图片描述

在进行网络编程之前,需要在项目中的.pro文件中添加network模块

实际开发中不会用Qt直接写服务器的,因为服务器是没有图形化界面的,一般我们会用其他的语言软件写好程序之后与Qt联合使用,这里只是演示

在实现网络编程的时候在pro文件中要加入network
在这里插入图片描述

1、UDP Socket

(1)核心API

方法说明
bind(const QHostAddress&,quint16)绑定指定的端口号
receiveDatagram返回QNetworkDatagram,读取一个UDP数据报
writeDatagram(const QNetworkDatagram&)发送一个UDP数据报
信号说明
readyRead在收到数据并准备就绪后触发
QNetworkDatagram
构造函数说明
QNetworkDatagram(const QByteArray& ,const QHostAddress& ,quint16)通过QByteArray,目标IP地址,目标端口号构造一个UDP数据报
方法说明
data获取数据报内部持有的数据,返回QByteArray
senderAddress获取数据报中包含的对端的IP地址
senderPort获取数据报中包含的对端的端口号

(2)回显服务器

回显服务器和回显客户端顾名思义就是我给服务器发送什么服务器给我发送什么

widget.cpp
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//修改窗口标题this->setWindowTitle("服务器");//创建udp实例socket = new QUdpSocket(this);//连接信号槽connect(socket,&QUdpSocket::readyRead,this,&Widget::processRequest);//绑定端口bool ret = socket->bind(QHostAddress::Any,9090);if(!ret){QMessageBox::critical(nullptr,"服务器启动有误",socket->errorString());return;}
}void Widget::processRequest()
{//读取请求const QNetworkDatagram& requestDatagram = socket->receiveDatagram();//解析请求QString request = requestDatagram.data();//根据请求计算响应const QString& response = process(request);//响应回写客户端QNetworkDatagram responseDatagram(response.toUtf8(),requestDatagram.senderAddress(),requestDatagram.senderPort());socket->writeDatagram(responseDatagram);//交互信息显示到窗口上QString log = "[" + requestDatagram.senderAddress().toString() + ":" + QString::number(requestDatagram.senderPort())+"}req: "+request+",resp:"+response;ui->listWidget->addItem(log);
}QString Widget::process(const QString &request)
{//对于回显服务器来说,请求就是回应,但是对于大型的商务服务器,这里的代码量是非常巨大的return request;
}

(3)回显客户端

widget.cpp
const QString& SERVER_IP = "127.0.0.1";//客户端IP地址
const quint16 SERVER_PORT = 9090;//客户端端口号Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//实例socket = new QUdpSocket(this);//窗口名this->setWindowTitle("客户端");//信号槽连接connect(socket,&QUdpSocket::readyRead,this,&Widget::processResponse);
}
//这个函数用来处理收到的响应
void Widget::processResponse()
{//读取解析响应const QNetworkDatagram& responseDatagram = socket->receiveDatagram();QString response = responseDatagram.data();//因为是回显服务器,直接将响应数据显示到界面上ui->listWidget->addItem("服务器:"+response);
}void Widget::on_pushButton_clicked()
{//获取到输入框的内容	const QString& text = ui->lineEdit->text();//构造请求数据QNetworkDatagram requestDatagram(text.toUtf8(),QHostAddress(SERVER_IP),SERVER_PORT);//发送请求数据socket->writeDatagram(requestDatagram);//发送的请求添加到列表框ui->listWidget->addItem("客户端:"+text);//清空输入框内容ui->lineEdit->setText("");
}

qudpsocket

2、TCP Socket

(1)核心API

主要有两个核心类

QTcpServer
方法说明
listen(const QHostAddress&,quint16 port)绑定指定的地址和端口号,并开始监听
nextPendingConnection从系统中获取到一个已经建立好的tcp连接,返回一个QTcpSocket,表示这个客户端的连接,通过这个socket对象完成和客户端之间的通信
信号说明
newConnection有新的客户端建立好之后触发
QTcpSocket
方法说明
readAll读取当前接收缓冲区中的所有数据并返回一个QByteArray对象
write(const QByteArray&)把数据写入socket中
deleteLater暂时把socket对象标记为无效,Qt会在下个事件循环中析构释放该对象
信号说明
readyRead有数据到达准备就绪时触发
disconnected断开连接时触发

(2)回显服务器

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 1. 修改窗口标题.this->setWindowTitle("服务器");// 2. 创建 QTcpServer 的实例tcpServer = new QTcpServer(this);// 3. 通过信号槽, 指定如何处理连接.connect(tcpServer, &QTcpServer::newConnection, this, &Widget::processConnection);// 4. 绑定并监听端口号. 一定要确保准备工作充分了, 再真正开张营业.//    这个操作得是初始化的最后一步. 都是需要把如何处理连接, 如何处理请求... 都准备好之后, 才能真正绑定端口并监听.bool ret = tcpServer->listen(QHostAddress::Any, 9090);if (!ret) {QMessageBox::critical(this, "服务器启动失败!", tcpServer->errorString());exit(1);}
}Widget::~Widget()
{delete ui;
}void Widget::processConnection()
{//通过tcpServer获得socket对象, 通过这个对象来和客户端进行通信QTcpSocket* clientSocket = tcpServer->nextPendingConnection();QString log = "[" + clientSocket->peerAddress().toString() + ":" + QString::number(clientSocket->peerPort()) + "] 客户端上线!";ui->listWidget->addItem(log);//通过信号槽, 来处理客户端发来请求的情况connect(clientSocket, &QTcpSocket::readyRead, this, [=]() {//读取出请求数据. 此处 readAll 返回的是 QByteArray, 通过赋值转成 QStringQString request = clientSocket->readAll();//根据请求处理响应const QString& response = process(request);//把响应写回到客户端clientSocket->write(response.toUtf8());//把上述信息记录到日志中QString log = "[" + clientSocket->peerAddress().toString() + ":" + QString::number(clientSocket->peerPort()) + "] "+ " req: " + request + ", resp: " + response;ui->listWidget->addItem(log);});//通过信号槽处理客户端断开连接情况connect(clientSocket, &QTcpSocket::disconnected, this, [=]() {//断开连接信息通过日志打印QString log = "[" + clientSocket->peerAddress().toString() + ":" + QString::number(clientSocket->peerPort()) + "] 客户端下线!";ui->listWidget->addItem(log);//手动释放 clientSocket. 使用deleteLater更加合适clientSocket->deleteLater();});
}//回显服务器.
QString Widget::process(const QString request)
{return request;
}

(3)回显客户端

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//设置窗口标题this->setWindowTitle("客户端");//创建socket实例socket = new QTcpSocket(this);//和服务器连接socket->connectToHost("127.0.0.1", 9090);//连接信号槽, 处理响应connect(socket, &QTcpSocket::readyRead, [=]() {// 读取出响应内容QString response = socket->readAll();// 把响应内容显示到界面上ui->listWidget->addItem("服务器说: " + response);});// 等待连接建立的结果. 确认是否连接成功bool ret = socket->waitForConnected();if (!ret) {QMessageBox::critical(this, "连接服务器出错", socket->errorString());exit(1);}
}Widget::~Widget()
{delete ui;
}void Widget::on_pushButton_clicked()
{// 获取到输入框中的内容const QString& text = ui->lineEdit->text();// 发送数据给服务器socket->write(text.toUtf8());// 把发的消息显示到界面上ui->listWidget->addItem("客户端说: " + text);// 清空输入框的内容ui->lineEdit->setText("");
}

qtcpsocket

3、HTTP Client

QNetworkAccessManager

提供核心操作

方法说明
get(const QNetworkRequest& )发起一个HTTP GET请求,返回QNetworkReply对象
post(const QNetworkRequest& ,const QByteArray& )发起一个HTTP POST请求,返回QNetworkReply对象
QNetworkRequest

表示一个HTTP请求,不含body,body是数据本体

方法说明
QNetworkRequest(const QUrl& )通过URL构造一个HTTP请求
setHeader(QNetworkRequest::KnowHeaders header,const QVariant& value)设置请求头
QNetworkReply
方法说明
error获取出错状态
errorString获取出错原因的文本
readAll读取响应body
header(QNetworkRequest::KnownHeaders header)读取相应指定header的值
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);manager = new QNetworkAccessManager(this);
}Widget::~Widget()
{delete ui;
}void Widget::on_pushButton_clicked()
{//获取到输⼊框中的URL, 构造QUrl对象QUrl url(ui->lineEdit->text());//构造HTTP请求对象QNetworkRequest request(url);//发送GET请求QNetworkReply* response = manager->get(request);//通过信号槽来处理响应connect(response, &QNetworkReply::finished, this, [=]() {if (response->error() == QNetworkReply::NoError){//响应正确QString html(response->readAll());ui->plainTextEdit->setPlainText(html);}else{//响应出错ui->plainTextEdit->setPlainText(response->errorString());}response->deleteLater();});
}

qhttp


今日分享就到这里了~

在这里插入图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词