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

护肤品网站模板计算机基础培训机构

护肤品网站模板,计算机基础培训机构,网站建设公司龙头,张家港外贸网站建设目录 前言 一、UDP网络编程 1.Qt项目文件 2.UDP类 QUdpSocket QNetworkDatagram 3.UDP回显服务器案例 细节 服务器设计 客户端设计 二、TCP网络编程 1.TCP类 QTcpServer QTcpSocket 2.TCP回显服务器案例 细节 服务器设计 客户端设计 三、HTTP客户端 1.HTTP…

目录

前言

一、UDP网络编程

1.Qt项目文件

2.UDP类

QUdpSocket

QNetworkDatagram

3.UDP回显服务器案例

细节

服务器设计

客户端设计

二、TCP网络编程

1.TCP类

QTcpServer

QTcpSocket

2.TCP回显服务器案例

细节

服务器设计

客户端设计

三、HTTP客户端

1.HTTP客户端类 

QNetworkAccessManager

QNetworkRequest

QNetworkReply

2.HTTP客户端案例


前言

        我们之前学习的系统相关的内容,在不同的系统下的理论和实现可能都不太一样,但是对于计算机网络模块来说,因为网络提供了不同主机之间的信息通信,那么如何想让两个主机进行通信,那么他们的通信模块,也就是计算机模块的实现也就必须是一样的才可以。所以说计算机网络模块的实现对于不同的系统也是一样的,最主要的区别就是在于语言层面上,对于网络编程的系统接口的封装。对于C++标准库中,一直是没有提供网络编程相关的API库。

        在整个网络协议栈来看,网络编程就是我们对于用户层的一种编写,但是我们想要传输数据的时候需要传输层协议的支持,但是传输层协议有两个,所以我们在应用层也需要采用一些接口去指定传输层协议。

一、UDP网络编程

1.Qt项目文件

        .pro文件是 Qt 项目文件。它是一个文本文件,包含了项目的各种信息和配置,用于指导qmake如何构建 Qt 项目。所以在Qt中进行网络编程之前,需要在项目当中的.pro文件中添加network模块来引入网络编程模块。在我们之前使用的所有控件都是包含在QtCore模块当中的,只不过默认生成.pro文件的时候就已经添加了。而且Qt来提供了很多其他的模块。

        Qt为什么要划分出这么多模块呢?因为Qt本身是一个非常大的框架,如果我们默认把所有Qt提高的功能模块全都一下引入项目当中,那么即使我们写一个简单的打印helloworld,那么生成的可执行程序也会 非常的大,可执行程序内部编译了许多用不到的内容。所以为了让生成的Qt项目更加的轻量化,那么就把不同的功能划分成了多个模块,我们需要使用的时候,就需要在.pro文件中引入包含了。

        而且为了让多模块的项目更加的轻量化,Qt也提高了模块的动态库和静态库的两种版本。 

2.UDP类

        Qt对于UDP的类有两个,一个是QUdpSocket表示udp通信套接字文件类,另一个是表示一个UDP数据报的类QNetworkDatagram类。

QUdpSocket
名称说明

bind(const QHostAddress&,  quint16)

绑定指定的端口号
receiveDatagram()返回一个UDP数据报对象
writeDatagram(const QNetworkDatagram&)发送一个UDP数据报
readyRead信号在收到数据并准备就绪后触发
  • 对于读取数据的操作,在C++语言层面的接口或者系统的底层原生接口默认都是阻塞方式的等待,当然也可以设置非阻塞,而Qt在处理读取数据操作的时候,并不是阻塞或者非阻塞等待的方式,而是采用信号槽机制,当有数据到来并就绪只会,就会发送readRead信号。
  • QHostAddress是一个用于表示IP地址的一个类,对于服务器来说设置为QHostAddress::Any即可,表示可以用于监听任何地址的连接,对于IPv4和IPv6都适用。
  • 对于bind函数可能会绑定失败,但是他会将失败的原因存放起来,可以通过errorString成员函数获取到失败信息。
QNetworkDatagram
名称说明
QNetworkDatagram(const QByteArray&, const HostAddress&, quint16)构造函数,通过QByteArray,目标ip和端口号构造一个UDP数据报
data()获取数据报内部持有的数据,返回一个QByteArray类型对象
senderAddress()获取数据报中包含的对端ip地址
senderPort()获取数据报中包含的对端端口号

3.UDP回显服务器案例

        只是一个使用网络接口的案例,因为一般来说服务器都不会带有图形化界面的。

细节
  • 在readyRead信号绑定槽函数和bind操作的顺序来说,要先绑定信号槽,后bind,因为一旦绑定ip和端口号之后,就可能会有通信数据到来了。那么在进行信号槽的绑定,就会来不及了,早到的数据就因为没有槽函数,所以不进行处理了。
  • 我们下面的服务器设计中带有了图形化界面,在配置文件.pro文件中也可以看到我们引入了gui模块,那么我们的云服务器默认是没有装配图形化界面的,所以是没有办法直接将我们下面写的服务器端代码放入到云服务器允许的。
  • 而对于我们现在写的Qt的udp客户端是可以直接连接linux服务器下的udp服务器的。所以说网络底层协议的实现都是一样的。udp都是一套逻辑。一般Qt都不会写服务器,大多数都是写客户端,然后用Qt客户端连接linux服务器。
服务器设计

widget.h文件

class Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();QString porcess(const QString& request);public slots:void processRequest();private:Ui::Widget *ui;//引入Udp成员QUdpSocket* socket;
};

widget.cpp文件 

#include "widget.h"
#include "ui_widget.h"
#include <QMessageBox>
#include <QNetworkDatagram>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//创建udp对象socket = new QUdpSocket(this);//设置窗口标题this->setWindowTitle("服务器");//连接信号槽connect(socket, &QUdpSocket::readyRead, this, &Widget::processRequest);//绑定端口号bool retbind = socket->bind(QHostAddress::Any, 8082);if(retbind == false){QMessageBox::critical(this, "服务器启动出错", socket->errorString());return;}}Widget::~Widget()
{delete ui;
}//但是我们这里是回显,所以没有什么处理过程
QString Widget::porcess(const QString &request)
{return request;
}void Widget::processRequest()
{//获取请求信息const QNetworkDatagram& udp_request =  socket->receiveDatagram();//转化为字符串类型QString data_request = udp_request.data();//处理请求const QString& data = porcess(data_request);//构建相应数据报QNetworkDatagram response(data.toUtf8(), udp_request.senderAddress(), udp_request.senderPort());//发送回客户端socket->writeDatagram(response);//把客户端发的信息显示到listWidget控件上QString log = "[" + udp_request.senderAddress().toString() + ":" + QString::number(udp_request.senderPort())+ "]" + "message:" + data_request;ui->listWidget->addItem(log);
}
客户端设计

widget.h文件

class Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private slots:void on_pushButton_clicked();private:Ui::Widget *ui;//引入udp对象QUdpSocket* socket;
};

widget.cpp文件

#include "widget.h"
#include "ui_widget.h"
#include <QNetworkDatagram>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, [=](){//获取数据报const QNetworkDatagram udp_response = socket->receiveDatagram();//读取数据const QString& data = udp_response.data();//写入对话框中ui->listWidget->addItem("服务器:" + data);});
}Widget::~Widget()
{delete ui;
}
//发送按钮
void Widget::on_pushButton_clicked()
{//获取输入框的内容const QString& text = ui->lineEdit->text();//构建请求数据报const QString ip = "127.0.0.1";const quint16 port = 8082;QNetworkDatagram data_request(text.toUtf8(), QHostAddress(ip), port);//发送数据socket->writeDatagram(data_request);//更新对话框中的内容ui->listWidget->addItem("客户端:" + text);//情况输入框ui->lineEdit->clear();
}

二、TCP网络编程

1.TCP类

        Qt对于TCP的类提供两个,第一个是QTcpServer用于监听端口,实现获取客户端连接的操作,相当于是listensocket以及对于bind、listen以及accept接口函数的一个封装。第二个是用于客户端和服务器之间数据交互的类QTcpSocket类。

QTcpServer
名称说明
listen(const QHostAddress&, quint16 port)绑定ip和端口号,并开始监听,相当于bind和listen的结合
nextPendingConnection()从系统当中获取到一个已经建立好的tcp连接,返回一个QTcpSocket对象,通过这个对象是实现与客户端之间的通信
newConnection信号有新的客户端建立连接完毕之后触发的信号
QTcpSocket
名称说明
readAll()读取当前接收缓冲区中的所有数据,返回QByteArray对象
write(const QByteArray&)把输入写入到socket的发送缓冲区中
deleteLater()暂时把socket对象标记为无效,Qt会在下个事件循环中析构释放该对象、
peerAddress()获取对端ip地址
peerPort()获取对端端口号

connectToHost( const QString &hostName, quint16 port)

向服务器发起连接
readyRead信号有数据到来并准备就绪触发
disconnected信号连接断开的时候触发

2.TCP回显服务器案例

细节
  • 对于客户端向服务器发起连接的connectToHost函数返回值为void类型,但是我们还是要判断是否连接成功了,所以QTcpSocket类中提供了waitForConnected函数,该函数的作用是让当前线程处理等待状态,直到连接成功,或者连接反馈错误为止,又或者说超时。
服务器设计

widget.h文件

class Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();public slots:void processConnection();private:Ui::Widget *ui;//引入Tcp对象QTcpServer* socket;
};

widget.cpp文件

#include "widget.h"
#include "ui_widget.h"
#include <QMessageBox>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//设置窗口标题this->setWindowTitle("服务器");//tcp对象实例化socket = new QTcpServer(this);//绑定newConnection的信号槽函数connect(socket, &QTcpServer::newConnection, this, &Widget::processConnection);//进行bind和listen操作bool retlisten = socket->listen(QHostAddress::Any, 8082);if(retlisten == false){QMessageBox::critical(this, "服务器启动失败", socket->errorString());return;}
}Widget::~Widget()
{delete ui;
}//获取新连接的信号处理函数
void Widget::processConnection()
{//获取新连接QTcpSocket* client = socket->nextPendingConnection();//构建日志QString log = "[" + client->peerAddress().toString() + ":" + QString::number(client->peerPort()) + "] 新客户端上线";ui->listWidget->addItem(log);//通过信号槽触发接收消息connect(client, &QTcpSocket::readyRead, this, [=](){//读取消息QString message = client->readAll();//处理消息--此处没有处理,只是回显//写回到客户端client->write(message.toUtf8());//构建日志QString log = "[" + client->peerAddress().toString() + ":" + QString::number(client->peerPort()) + "] say: " + message;//写到界面ui->listWidget->addItem(log);});//处理断开连接的信号槽函数connect(client, &QTcpSocket::disconnected, this, [=](){//构建日志QString log = "[" + client->peerAddress().toString() + ":" + QString::number(client->peerPort()) + "] 客户端下线";//释放对象client->deleteLater();});
}
客户端设计

widget.h文件

class Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private slots:void on_pushButton_clicked();private:Ui::Widget *ui;//构建tcp对象QTcpSocket* socket;
};

widget.cpp文件

#include "widget.h"
#include "ui_widget.h"
#include <QMessageBox>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//设置窗口标题this->setWindowTitle("客户端 ");//实例化tcp对象socket = new QTcpSocket(this);//向服务器发起连接socket->connectToHost("127.0.0.1", 8082);//确认是否连接成功if(!socket->waitForConnected()){QMessageBox::critical(this, "连接服务器出错", socket->errorString());return;}//绑定接收到消息的信号槽函数connect(socket, &QTcpSocket::readyRead, this, [=](){//获取接收到的内容QString message = socket->readAll();//将内容打印到对话框中QString log = "服务器: " + message;ui->listWidget->addItem(log);});
}Widget::~Widget()
{delete ui;
}void Widget::on_pushButton_clicked()
{//获取输入框的内容QString message = ui->lineEdit->text();//将内容发送给服务器socket->write(message.toUtf8());//将内容打印到对话框中ui->listWidget->addItem("客户端: " + message);//情况输入框ui->lineEdit->clear();
}

三、HTTP客户端

1.HTTP客户端类 

        Qt中为HTTP协议的客户端主要提供了三个类,一个是QNetworkAccessManager类,该类提供了HTTP有关的核心操作。第二个类是QNetworkRequest类表示一个不含body的HTTP请求。第三个类就是QNetworkReply类,表示一个HTTP的响应。

        上述也说了真正的服务器一定也不会使用Qt就实现,所以Qt就没有提供服务端相关的HTTP类。

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

        一个HTTP协议的完整报文应该是包括报头和有效载荷的,而这个类只是实现了一个报头,对于有效载荷该类不进行实现,而且对于请求报文来说一般都不会带有一些实质性的内容,只会传递一些kv形式的参数内容,通过post方法来传递,所以post方法也为我们提供了传递kv的参数。

方法说明
QNetworkRequest(const QUrl&)通过Url构造一个HTTP请求
setHeader(QNetworkRequest::knownHeaders header, const QVariant& value)设置请求头部字段

        对于报头的请求行字段,Qt也进行了一定的封装,方便我们去设置请求行,Qt中采用的是枚举类型将常用的请求行字段进行一一列举出来,QNetworkRequest::knownHeaders就是该枚举对象。 

        对于QVariant类对象表示一个类型可变的值。

QNetworkReply
方法说明
error()获取出错状态
errorString()获取出错原因的字符串描述
readAll()获取响应的body字段
header(QNetworkRequest::knownHeaders header)获取响应头部字段
finished信号当客户端收到一个完整的响应报文只会触发

2.HTTP客户端案例

细节

  • 如何想要显示出来元素的HTML报文,那么就不可以使用QTextEdit控件,因为他会对HTML代码进行渲染,显示出来的就不是原始的HTML报文了,所以需要使用QPlainTextEidt控件。
  • 对于get、post等系列函数只是负责发送请求,不负责请求的等待,所以说他返回的响应对象是一个没有实际内容的对象,那什么时候才收到响应呢?依靠的是finished信号,通过信号槽机制去处理finished信号,也就相当于处理响应了。
#include "widget.h"
#include "ui_widget.h"
#include <QNetworkReply>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,并构建一个url对象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_data = response->readAll();ui->plainTextEdit->setPlainText(html_data);}else{ui->plainTextEdit->setPlainText(response->errorString());}//释放response对象response->deleteLater();});
}

http://www.dt0577.cn/news/40874.html

相关文章:

  • 南通 外贸建站推广网站最有效办法
  • phpcmsv9网站建设入门教程sem竞价代运营
  • 一个网站可以做多少弹窗广告搜索引擎优化包括哪些内容
  • 聊天网站开发外贸网站搭建推广
  • 哪个网站的前台背景墙做的好app推广一手单
  • 做h5哪些网站好 知乎seo商学院
  • html5网站模板 站长网nba交易最新消息
  • 许昌网站开发哪家好怎么自己做一个网页
  • 网站建设如何做好整体色彩搭配百度精准营销获客平台
  • 视屏网站的审核是怎么做的西安做网站
  • c 做的网站最近的时事新闻
  • 衡水住房和城乡建设局网站网站怎么弄
  • 郑州专门做网站的公司百度广告联盟赚广告费
  • 凤岗金属制品东莞网站建设技术支持seo如何优化排名
  • 中国建设银行官网网站学seo如何入门
  • 公司建网站要多少钱网站关键词排名怎么优化
  • 网站过期后百度seo优化排名
  • 幼儿园校园文化设计公司靠谱seo整站优化外包
  • 腾讯云wordpress搭建网站东莞seo建站投放
  • 三级做视频网站有哪些黑龙江暴雪预警
  • 郑州网站建设设计公司seo个人优化方案案例
  • 网站后台管理界面下载免费注册推广网站
  • 深圳旅游网站建设怎样交换友情链接
  • 网站用视频做背景网络营销专业技能
  • 阿里巴巴做网站需要多少钱网站建设企业建站
  • 环保主题网站模板网络推广优化服务
  • 啥十小企业网站建设北京seo顾问外包
  • 推荐网站网页自媒体平台排名
  • 百度做的网站后台怎么建设网站优化公司哪家效果好
  • 莆田做网站公司电话seo百度发包工具