当前位置: 首页 > news >正文

4、QT中的网络编程

一、Linux中的网络编程

1、子网和公网的概念

  • 子网网络:局域网,只能进行内网的通信
  • 公网网络:因特网,服务器等可以进行远程的通信

2、网络分层模型

4层模型:应用层、传输层、网络层、物理层

  • 应用层:用户自定义的网络数据传输协议:ssh、tftp、tfp、http 等
  • 传输层:tcp/udp出传输协议
  • 网络层:IPV4/IPV6,3G,4G,5G等网络协议
  • 物理层:光纤、路由器、网线、网卡

3、Tcp与Udp协议的区别

  • 三次握手:第一次握手就是客户端给服务器端发送一个报文,第二次就是服务器收到报文之后,会应答一个报文给客户端,第三次握手就是客户端收到报文后再给服务器发送一个报文,三次握手就成功了。(进行三次握手的主要作用就是为了确认双方的接收能力和发送能力是否正常)

  • Tcp传输协议:可靠传输协议,Tcp需要三步握手连接,每次通信都会进行数据的校验

  • Tcp的应用:一般用于文件的传输、控制命令的传输

  • Udp传输协议:不可靠传输协议,Udp传输不需要建立连接,Udp不会进行数据校验

  • Udp的应用:一般用于多媒体的数据传传输:屏幕广播软件、视频网站、直播软件

二、TCP通信

1、QTcpSocket Class 客户端类

Header: #include 头文件
qmake: QT += network 模块
Inherits: QAbstractSocket 父类
Inherited By: QSctpSocket and QSslSocket 派生类

在这里插入图片描述

2、函数接口

构造函数:
QTcpSocket(QObject *parent = nullptr)
//链接服务器 IP+端口
connectToHost(const QHostAddress &, quint16, QIODevice::OpenMode )
QHostAddress : IP地址
quint16 : 端口号
------------------------------------------------------------------
//直接填写IP 地址即可链接
connectToHost(const QString &, quint16, QIODevice::OpenMode, QAbstractSocket::NetworkLayerProtocol )
例子:
socket->connectToHost("192.168.25.2",1000);

3、数据的收发

//数据的发送
write(const char *, qint64 ) //发送 qint64大的数据
write(const char *)//直接发送字符数据
write(const QByteArray &) //发生QByteArray类型的数据//数据的接收
qint64 read(char *, qint64 ) //读取 qint64大的数据到 char * 地址 上
QByteArray read(qint64 ) //读取 qint64 大的数据 并返回
QByteArray readAll() //读取所有数据
//关联可读信号
[signal] void QIODevice::readyRead()

4、QTcpServer Class 服务器类

Header: #include
qmake: QT += network
Inherits: QObject
Inherited By: QSctpServer

5、函数接口:

构造函数:
QTcpServer(QObject *parent = nullptr)
//绑定并监听接口
bool QTcpServer::listen(const QHostAddress &address = QHostAddress::Any, quint16 port= 0)
QHostAddress::Any : 相当于 INADDR_ANY.自动监听本地的所有地址
port : 取值范围 0 - 65535,尽量用 1000 以后的,因为 1000前,系统占用
例子: 监听本地IP地址
server->listen(QHostAddress::Any,6666)接收链接请求:
//服务器新的链接信号
[signal] void QTcpServer::newConnection()
//服务器 产生新的对象
[virtual] QTcpSocket*QTcpServer::nextPendingConnection()

6、数据的收发 :

//产生新的通信对象
QTcpSocket *new_socket = server->nextPendingConnection();
//通过的新的对象进行数据的收发
write(const char *, qint64 ) //发送 qint64大的数据
write(const char *)//直接发送字符数据
write(const QByteArray &) //发生QByteArray类型的数据
//接收数据
//1.关联新的对象的可读 信号
[signal] void QIODevice::readyRead()
//2.在槽函数中读取数据
qint64 read(char *, qint64 ) //读取qint64 大的数据到 char * 地址 上
QByteArray read(qint64 ) //读取 qint64大的数据 并返回
QByteArray readAll() //读取所有数据

练习:实现客户端与调试助手的双向通信

①、服务端:Server.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);//1、创建一个服务器对象server = new QTcpServer(this);//2、开始监听if(server->listen(QHostAddress :: Any, 7777)){qDebug() << "监听成功" << endl;}else{qDebug() << "监听失败" << endl;}//3、关联新的链接信号connect(server, SIGNAL(newConnection()), this, SLOT(accept_connect()));
}MainWindow::~MainWindow()
{delete ui;
}int i=0;
QTcpSocket *new_socket ;void MainWindow :: accept_connect()
{qDebug() << "有新的链接请求处理" << endl;//产生新的通信对象new_socket = server->nextPendingConnection();//哪里产生对象,就哪里关联connect(new_socket, SIGNAL(readyRead()), this, SLOT(read_data()));
}//收到信息读取
void MainWindow :: read_data()
{QString msg = new_socket->readAll();//取出发送者的IP地址qDebug() << new_socket->peerAddress() << endl;qDebug() << msg <<endl;//显示收到信息ui->textBrowser->setText(msg);
}//发送信息给客户端
void MainWindow::on_pushButton_clicked()
{QString msg = ui->textEdit->toPlainText();new_socket->write(msg.toUtf8());
}

②、服务端:Client.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"QTcpSocket *socket;
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);//1、创建客户端通信对象socket = new QTcpSocket(this);//2、链接服务器socket->connectToHost("192.168.124.54", 7777);//3、数据的发送socket->write("Hello ");//4、关联刻度信号connect(socket, SIGNAL(readyRead()), this, SLOT(read_date()));
}MainWindow::~MainWindow()
{delete ui;
}//读取信息
void MainWindow::read_date()
{QString msg = socket->readAll();//显示收到信息ui->textBrowser->setText(msg);
}//发送信息
void MainWindow::on_pushButton_clicked()
{QString msg = ui->textEdit->toPlainText();socket->write(msg.toUtf8());
}

三、UDP通信

在这里插入图片描述

1、QUdpSocket Class类

Header: #include 头文件
qmake: QT += network 模块
Inherits: QAbstractSocket 父类

2、函数接口:

构造函数:
QUdpSocket(QObject *parent = nullptr)
发送数据的接口:
qint64 writeDatagram(const char *data, qint64 size, const QHostAddress &address,quint16 port)
data:需要发送的数据
size:数据的大小
address:接收端的IP
port : 接收端的端口
qint64 writeDatagram(const QByteArray &datagram, const QHostAddress &host, quint16 port)

3、接收端:

1.绑定UDP socket
bool QAbstractSocket::bind(const QHostAddress &address, quint16 port = 0)
address:需要绑定的地址
port:需要绑定的端口2.读取数据
qint64 QUdpSocket::readDatagram(char *data, qint64 maxSize, QHostAddress *address =nullptr, quint16 *port = nullptr)
data:读取后数据的存放地址
maxSize:读取的数据最大值
address:发送者的IP
port:发生者的端口QNetworkDatagram QUdpSocket::receiveDatagram(qint64 maxSize = -1)
QNetworkDatagram 网络数据管理类
QHostAddress senderAddress() const //发送者的IP
int senderPort() const //发生者端口
int destinationPort() const 获取对方的端口

练习:

①、接收端:recv.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QNetworkDatagram>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);//1、创建接收端socket = new QUdpSocket(this);//2、绑定if(socket->bind(QHostAddress::Any, 7777)){qDebug() << "绑定成功" << endl;}else{qDebug() << "绑定失败" << endl;}//3、关联可读信号connect(socket, SIGNAL(readyRead()), this, SLOT(readData()));
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::readData()
{qDebug() << "读取数据" << endl;//判断是否有网络数据while (socket->hasPendingDatagrams()){//把所有的数据读取到msgQNetworkDatagram msg = socket->receiveDatagram();//输出IP和Port信息qDebug() << msg.senderAddress().toString() << endl;qDebug() << msg.senderPort() << endl;//把发送端发送的数据转化为原来的QString类型数据QString decodeMsg = QString :: fromUtf8(msg.data());//输出数据qDebug() << decodeMsg << endl;}
}

②、发送端:send.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QString>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);//1、创建发送端socket = new QUdpSocket(this);}MainWindow::~MainWindow()
{delete ui;
}//按键按下发送信息
void MainWindow::on_pushButton_clicked()
{//获取对话框信息QString msg = ui->lineEdit->text();//利用套接字发送信息socket->writeDatagram(ui->lineEdit->text().toUtf8(), QHostAddress("192.168.124.54"), 7777);
}

四、HTTP 请求

超文本传输协议(Hyper Text Transfer Protocol,HTTP)是一个简单的请求-响应协议,它通常运行在TCP之上。它指定了客户端可能发送给服务器什么样的信息以及得到什么样的响应
简单理解:客户通过http请求协议从服务器中获取需要的数据

免费API接口

http://api.qingyunke.com/ //机器人 api
舔狗API 官网
http://v2.alapi.cn
http://v2.alapi.cn/api/dog?
token=3ydsG67GrDABA97n(自己的token)
http://v2.alapi.cn/api/acg?
token=3ydsG67GrDABA97n(自己的token)
http://v2.alapi.cn/api/acg?
token=3ydsG67GrDABA97n(自己的token)

五、QT 中的HTTP 请求

1、QNetworkAccessManager Class网络请求管理器

Header: #include
qmake: QT += network
Since: Qt 4.4
Inherits: QObject

2、官方的请求 demo

//1.新建网络请求 管理器
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
//关联管理器的 finished 信号
connect(manager,&QNetworkAccessManager::finished,this, &MyClass::replyFinished);
//2.往http://qt-project.org 网站发起请求
manager->get(QNetworkRequest(QUrl("http://qtproject.org")));
网络请求信号:
void finished(QNetworkReply *reply)

在这里插入图片描述

3、QNetworkReply Class 网络请求数据管理器

Header: #include
qmake: QT += network
Since: Qt 4.4
Inherits: QIODevice

4、函数接口

//读取所有网络返回的数据
readAll()
//信号
void downloadProgress(qint64 bytesReceived,
qint64 bytesTotal) 下载进度信号
void finished() 下载完毕信号
void readyRead() 有数据可读信号

练习:获取舔狗API的数据

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
//添加网络请求管理器
#include <QNetworkAccessManager>
#include <QLabel>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);//1、新建网络请求管理器QNetworkAccessManager *manager = new QNetworkAccessManager(this);//2、关联管理器的finished信号connect(manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(replyFinished(QNetworkReply *)));//3、往http://qt-project.org 网站发起请求manager->get(QNetworkRequest(QUrl("http://v2.alapi.cn/api/dog?token=1tXlTpqdAcx4jXVm")));
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::replyFinished(QNetworkReply *reply)
{//读取所有的网络数据QString  msg = reply->readAll();ui->textBrowser->setText(msg);}
  • 注意:假如QT不能使用https,可以把https改为http
http://www.lryc.cn/news/160718.html

相关文章:

  • 单例模式(饿汉式单例 VS 懒汉式单例)
  • Oracle数据库连接之TNS-12541异常
  • sql中的排序函数dense_rank(),RANK()和row_number()
  • Flask狼书笔记 | 05_数据库
  • HJ70 矩阵乘法计算量估算
  • Doris数据库使用记录
  • 华为OD机试真题【篮球比赛】
  • sublime text 格式化json快捷键配置
  • Spring Cloud 面试题总结
  • 如何实现24/7客户服务自动化?
  • 2022年12月 C/C++(六级)真题解析#中国电子学会#全国青少年软件编程等级考试
  • 【Spring Cloud系列】 雪花算法原理及实现
  • Postgresql 阿里云部署排雷
  • l8-d10 TCP协议是如何实现可靠传输的
  • 9月9日扒面经
  • 项目实战:ES的增加数据和查询数据
  • vs code调试rust乱码问题解决方案
  • 大数据课程K22——Spark的SparkSQL的API调用
  • 数据结构学习系列之顺序表的两种删除方式
  • 机器学习笔记之最优化理论与方法(七)无约束优化问题——常用求解方法(上)
  • ES-索引管理
  • linux中常用shell脚本整理
  • 介绍PHP
  • selenium+find_elements用法
  • 1DM+下载器_11.2.1魔改增强版下载
  • vue3:3、项目目录和关键文件
  • ChatGPT实战与私有化大模型落地
  • 10分钟从实现和使用场景聊聊并发包下的阻塞队列
  • Python入门学习13(面向对象)
  • 哈工大计算机网络课程网络安全基本原理之:身份认证