wordpress制作的网站模板,一米电子产品营销型网站案例展示,百度推广服务费3000元,体育网站建设规划文章目录 前言#xff1a;1. Qt 网络编程介绍1.1 什么是网络编程#xff1f;1.2 Qt的模块 2. UDP Socket2.1 核心 API 概述2.2 写一个带有界面的 Udp 回显服务器2.3 写一个带有界面的 Udp 客户端 3. TCP Socket3.1 核心 API 概述3.2 代码#xff1a; 4. HTTP Client4.1 核心… 文章目录 前言1. Qt 网络编程介绍1.1 什么是网络编程1.2 Qt的模块 2. UDP Socket2.1 核心 API 概述2.2 写一个带有界面的 Udp 回显服务器2.3 写一个带有界面的 Udp 客户端 3. TCP Socket3.1 核心 API 概述3.2 代码 4. HTTP Client4.1 核心API4.2 代码示例 总结 前言
在当今信息化社会网络编程已成为软件开发中不可或缺的一部分。Qt作为一个跨平台的应用程序框架提供了丰富的网络编程API使得开发者能够便捷地实现客户端和服务器之间的通信。本文将深入探讨Qt网络编程的基本概念、核心API以及实际应用示例帮助读者理解并掌握使用Qt进行网络编程的方法。
1. Qt 网络编程介绍
1.1 什么是网络编程
网络编程操作系统提供了一组APISocket API C标准库中并没有提供网络编程的 api 的封装。 进行网络编程的时候本质是在编写应用层代码需要传输层进行支持。 传输层最核心的协议有 UDP 和 TCP并且这两协议差别还很大。 Qt 也提供了两套 API。
1.2 Qt的模块
使用 Qt 网络编程的 API需要在 .pro 文件中添加 network 模块 之前我们学过的 Qt 的各种控件各种内容都是包含在QtCore 模块中默认就添加的
为什么Qt要划分出这些模块呢 Qt本身是一个非常庞大包罗万象的框架。 如果把所有的 Qt 的功能都放到一起即使咱们就只写一个简单的 hello world, 此时生产的可执行文件也会非常庞大。这里就包含了大量其实没有使用的功能
模块化处理 其他的功能分别封装成不同的模块默认情况下这些额外的模块不会参与编译。 需要在.pro文件中引入对应的模块才能把对应功能给编译加载进来。
Qt 其实提供了静态库的版本和动态库的版本。
2. UDP Socket
2.1 核心 API 概述
主要有两个 QUdpSocket一个文件 和 QNetworkDatagram数据包UDP是面向数据报的
QUdpSocket 表示一个 UDP 的 socket 文件。 readyRead当socket 收到请求的时候QUdpSocket 就会触发这个信号。 此时就可在槽函数里完成读取请求的操作了。 基于信号槽就天然达成了事件驱动这样的一种网络编程的方式 QNetWorkDatagram 表示一个UDP数据报
2.2 写一个带有界面的 Udp 回显服务器
一个正经的服务器很少会有图形化界面一般都是命令行 Qt 也是完全可以编写控制台程序的。
在 .pro 文件中添加一个network 注意一定是先连接信号槽后绑定端口号。 一旦绑定端口了意味着请求就可以被收到了 如果在绑定之后在连接信号槽之前有客户端把请求发过来了此时就可能读不到这样的请求(就没了) // 绑定端口号
socket-bind(QHostAddress::Any, 9090);一个端口号只能被一个socket绑定万一9090被别人绑定了呢 返回绑定失败信息
代码
#include widget.h
#include ui_widget.h
#include QMessageBox
#include QNetworkDatagramWidget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui-setupUi(this);// 创建出这个对象socket new QUdpSocket(this); // this 是用于通过对象树自动delete掉对象的// 不然就要在析构中去手动delete掉// 设置窗口标题this-setWindowTitle(服务器);// 连接信号槽connect(socket, QUdpSocket::readyRead, this, Widget::processRequest);// 绑定端口号bool ret socket-bind(QHostAddress::Any, 9090);if (!ret) {// 绑定失败QMessageBox::critical(this, 服务器启动出错, socket-errorString());// socket-本质上也是对系统的errno机制进行封装 相当与Linux中的perrorreturn;}}Widget::~Widget()
{delete ui;
}// 这个函数完成的逻辑就是服务器的最核心逻辑了
void Widget::processRequest()
{// 1. 读取请求并解析const QNetworkDatagram requestDatagram socket-receiveDatagram();QString request requestDatagram.data(); // .data() 返回的是一个QByteArray// QByteArray 是可以赋值给QString// 2. 根据请求计算响应由于是回显服务器响应不需要计算就是请求本身const QString response process(request);// 3. 把响应写回客户端QNetworkDatagram responseDatagram(response.toUtf8(), requestDatagram.senderAddress(), requestDatagram.senderPort());// .toUtf8 取出QString 内部的字节数组,客户端是谁就包含在requestDatagram中了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;
}2.3 写一个带有界面的 Udp 客户端 Qt Creator 中是可以同时打开多个项目。此时如果这俩项目中存在同名文件就非常容易混淆。
此时写的客户端要能够主动给服务器发起请求
// 定义两个常量来描述服务器的 地址 和 端口
const QString SERVER_IP 127.0.0.1;
const quint16 PORT 9090; 端口号本质上是一个 2字节的 无符号 整数quint16本质上就是一个unsigned short虽然short通常都是2字节但是C标准中没有明确规定这一点只是说short不应该少于2个字节。 什么时候用引用什么时候用赋值
const QNetworkDatagram responseDatagram socket-receiveDatagram();
QString response responseDatagram.data();啥时候使用引用类型啥时候使用值类型需要平时写代码的时候多去思考多去注意的 大的原则肯定是能用引用尽量用引用但有的时候注意到尤其是上面这种不同的值进行互相转换的时候大概率是要用值类型的 代码
#include widget.h
#include ui_widget.h
#include QNetworkDatagram// 定义两个常量来描述服务器的 地址 和 端口
const QString SERVER_IP 127.0.0.1;
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);
}Widget::~Widget()
{delete ui;
}void Widget::on_pushButton_clicked()
{// 1. 获取到输入框的内容const QString text ui-textEdit-toPlainText();// 2. 构造 UDP 的请求数据QNetworkDatagram requestDatagram(text.toUtf8(), QHostAddress(SERVER_IP), SERVER_PORT); // 这里字符串的IP要转换为点分十进制的IP// 3. 发送请求数据socket-writeDatagram(requestDatagram);// 4. 把发送的请求也添加到列表框中ui-listWidget-addItem(客户端说 text);// 5. 把输入框的内容也清空一下ui-textEdit-setText();
}void Widget::processResponse()
{// 通过这个函数来处理收到的响应// 1. 读取到响应数据const QNetworkDatagram responseDatagram socket-receiveDatagram();QString response responseDatagram.data();// 啥时候使用引用类型啥时候使用值类型需要平时写代码的时候多去思考多去注意的// 大的原则肯定是能用引用尽量用引用但有的时候注意到尤其是上面这种不同的值进行互相转换的时候大概率是要用值类型的// 2. 把响应数据显示到界面上ui-listWidget-addItem(服务器说 response);
}如何启动多个客户端 多启动几个可执行程序就好 之前学Linux网络编程的时候是使用云服务器部署服务器程序其它的同学们也能连上。
能否把现在的UDP服务器放到云服务器上呢 大概率不行取决于你的服务器是否安装了图形化界面Qt程序需要依赖于图形化界面来运行的Linux的云服务器一般都是没有图形化界面的如果需要你需要手动额外安装。作为一个服务器本身就是没有图形界面的此处只是为了演示Qt网络编程的情况也不会使用Qt来写服务器程序 能否使用先在的UDP客户端连接Linux上写的UDP服务器呢 这是完全OK的这也是网络编程/协议的意义 一般商业公司的项目都是通过其它方式编写的服务器程序大概率不会是Qt但是使用Qt编写客户端 3. TCP Socket
UDP 属于无连接不可靠传输面向数据报全双工TCP 有连接可靠传输面向字节流全双工 因此TCP的代码要比UDP稍微复杂一点点
三次握手四次挥手TCP建立链接或断开链接的时候完成的操作系统系统内核负责完成的 应用层的代码只能告诉内核我要发起一个连接客户端或者告诉内核我要拿到一个已经建立好的连接服务器
3.1 核心 API 概述
核心类是QTcpServer 和 QTcpSocket
QTcpServer 用于监听客户端口和获取客户端连接 QTcpSocket 用户客户端和服务器之间的数据交互 事件循环简单理解可以认为是Qt程序内部带有一个“生物钟”这样的东西周期性的执行一些逻辑 QByteArray ⽤于表⽰⼀个字节数组. 可以很⽅便的和 QString 进⾏相互转换. 例如: 使⽤ QString 的构造函数即可把 QByteArray 转成 QString。使⽤ QString 的 toUtf8 函数即可把 QString 转成 QByteArray。 // 2. 通过信号槽来处理客户端发来请求的情况// 2. 通过信号槽来处理客户端发来请求的情况connect(clientSocket, QTcpSocket::readyRead, this, [](){// a)读取出请求数据,此处readAll 返回的是QByteArray, 通过赋值转成 QStringQString request clientSocket-readAll();// b)根据请求处理响应const QString response process(request);// c) 把响应写回到客户端clientSocket-write(response.toUtf8());// d)把上述信息记录到日志中QString log [ clientSocket-peerAddress().toString() : QString::number(clientSocket-peerPort()) ] req: request , resp: response;ui-listWidget-addItem(log);});在Linux 网络编程需要搞一个循环循环的读取请求循环处理… 在 Qt 中基于信号槽就不必循环了 每次客户端发来请求都能触发 readyRead 信号。 即使多个请求槽函数也是可以顺利的执行到的 上述的代码其实是不够严谨作为回显服务器是已经够了的 实际上使用TCP的过程中TCP是面向字节流的一个完整的请求可能分成多段字节数组进行传输 虽然TCP已经帮我们处理了很多棘手的问题了但是TCP本身不负责区分从哪里到哪里是一个完整的应用层数据报粘包问题。 更严谨的做法应该是每次收到的数据都给放到一个大的字节数组缓冲区中并且提前约定好应用层的协议的格式分隔符长度其它办法 再按照协议格式对缓冲区进行更细致的解析处理当前不打算写这么复杂了再按照协议格式对缓冲区数据进行更细致的解析处理 QTcpSocket* clientSocket每个客户端都有一个这样的对象存在N个的随着服务器的运行客户端越来越多如果不释放此时累计的clientSocket也会越来越多 QTcpServer QUdpSocket都是只有一份的就算不释放影响不大 内存泄漏其实影响不大但是如果是文件描述符泄漏呢? 现在的机器内存都很大而文件描述符表的长度则是操作系统的一个参数。Linux可以通过ulimits 命令来查看和调整 // b) 手动释放 clientSocket
delete clientSocket;一旦要是 delete 就意味着其它逻辑无法使用 clientSocket
务必要保证delete 是这个槽函数的最后一步而且也要保证 delete 肯定能执行到不会被return / 抛出异常 给跳过…
clientSocket-deleteLater();直接使用delete是下策使用deleteLater 更加合适 这个操作不是立即销毁 clientSocket, 而是告诉Qt下一轮事件循环中槽函数都是在事件循环中执行的进入到下一轮事件循环意味着上一轮事件循环肯定结束了也以为着当前的槽函数肯定是结束了再进行上述销毁操作 当然上述做法都是权宜之计相比之下Java/Python/Go 等全自动化垃圾回收更好用一些 socket-connectToHost(127.0.0.1, 9090);在Linux写的TCP的回显服务器的时候遇到了一个问题多个客户端同时访问的时候就只会有一个生效后来引入了多线程每个客户端安排一个单独的 线程每个客户端安排一个单独的线程问题才得到改善 在Linux中之所以出现上述问题和TCP和多线程都没啥关系。从来没有说法说TCP服务器必须使用多线程编写 之前存在这个问题的本质原因是写了一个双重循环里层循环没有及时结束导致外层循环不能快速的第二次调用到accept,导致第二个客户端无法处理了 引入多线程本质上就是把双重循环化简成为两个独立的循环。 而在咱们Qt的服务器中其实一个循环都没写是通过Qt内置的信号槽来驱动的 信号槽机制很好的化简了咱们的程序但是基本没有正经的服务器用Qt来写
3.2 代码
服务端
#include widget.h
#include ui_widget.h
#include QMessageBox
#include QTcpSocketWidget::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()
{// 1. 通过tcpServer拿到一个socket对象通过这个对象和客户端进行通信QTcpSocket* clientSocket tcpServer-nextPendingConnection();QString log [ clientSocket-peerAddress().toString() : QString::number(clientSocket-peerPort()) ]客户端上线;ui-listWidget-addItem(log);// 2. 通过信号槽来处理客户端发来请求的情况connect(clientSocket, QTcpSocket::readyRead, this, [](){// a)读取出请求数据,此处readAll 返回的是QByteArray, 通过赋值转成 QStringQString request clientSocket-readAll();// b)根据请求处理响应const QString response process(request);// c) 把响应写回到客户端clientSocket-write(response.toUtf8());// d)把上述信息记录到日志中QString log [ clientSocket-peerAddress().toString() : QString::number(clientSocket-peerPort()) ] req: request , resp: response;ui-listWidget-addItem(log);});// 3. 通过信号槽来处理客户端断开连接的情况connect(clientSocket, QTcpSocket::disconnected, this, [](){// a) 把断开连接的连接的信息通过日志显示出来QString log [ clientSocket-peerAddress().toString() : QString::number(clientSocket-peerPort()) ] 客户端下线;ui-listWidget-addItem(log);
// // b) 手动释放 clientSocket, 直接使用delete是下策使用deleteLater 更加合适
// delete clientSocket;clientSocket-deleteLater();});
}// 此处写的是回显服务器
QString Widget::process(const QString request)
{return request;
}客户端 #include widget.h
#include ui_widget.h
#include QMessageBoxWidget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui-setupUi(this);// 1. 设置窗口标题this-setWindowTitle(客户端);// 2. 创建socket对象实例socket new QTcpSocket(this);// 3. 和服务器建立连接socket-connectToHost(127.0.0.1, 9090);// 调用者个函数此时系统内核就会和对方的服务器之间进行三次握手了// 三次握手也是需要消耗一定的时间的// 4. 连接信号槽处理响应connect(socket, QTcpSocket::readyRead, this, [](){// a) 读取出响应内容QString response socket-readAll();// b) 把显示内容显示到界面上ui-listWidget-addItem(服务器说 response);});// 5. 等待连接建立的结果确认是否连接成功bool ret socket-waitForConnected();if (!ret){QMessageBox::critical(this, 连接服务器出错, socket-errorString());exit(1);}
}Widget::~Widget()
{delete ui;
}void Widget::on_pushButton_clicked()
{// 1. 获取到输入框内容中的const QString text ui-lineEdit-text();// 2. 发送数据给服务器socket-write(text.toUtf8());// 3. 把发送的消息显示到界面上ui-listWidget-addItem(客户端说 text);// 4. 清空输入框的内容ui-lineEdit-setText();
}4. HTTP Client
进行Qt开发时和服务器之间的通信很多时候也会用到HTTP协议
通过HTTP从服务器获取数据通过HTTP向服务端提交数据 HTTP 使用比 TCP/UDP 更多一些。 Qt中也提供了HTTP的客户端HTTP协议本质上也就是基于TCP协议实现的实现一个HTTP客户端/服务器本质上就是基于TCP socket 进行封装。 HTTP客户端Qt只是提供了HTTP客户端而没有提供HTTP服务器的库 4.1 核心API
关键类主要是三个 QNetworkAccessManager, QNetworkRequest, QNetworkReplyQNetworkAccessManager 提供了HTTP的核心操作。 QNetworkAccessManager 提供了HTTP的核心操作 QNetworkRequest 表示一个HTTP请求不含body 如果需要发送一个带有body的请求(比如post)会在QNetworkAccessManager的post方法中通过单独的参数来传入body。 QVariant 表示一个“类型可变”的值类似于 C 语言中的void*泛型编程虽然在C中还是挺常见的但是使用门槛还是比较高里面有一些坑 其中的 QNetworkRequest::KnownHeaders 是一个枚举类型常用取值 QNetworkReply 表示一个HTTP响应这个类同时也是QIODevice的子类 此外QNetworkReply 还有一个重要的信号finished 会在客户端收到完整的响应数据之后触发
4.2 代码示例
给服务器发送一个GET请求 此处显示的响应结果大概率是一个HTMLQPlainTextEdit 来进行表示能够看到响应的原始模样 QTextEidit(天然支持对HTML的解析)会对HTML进行解析渲染最终显示的效果就不是原始的HTML。QTextEdit 背后还做了很多工作当得到的HTML比较大的时候也会造成卡顿 QNetworkReply* response manager-get(request);get本身不是阻塞函数get只是负责发出去请求不负责等待响应回来 finished 信号 代码
#include mainwindow.h
#include ui_mainwindow.h
#include QNetworkReplyMainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui-setupUi(this);this-setWindowTitle(客户端);manager new QNetworkAccessManager(this);
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::on_pushButton_clicked()
{// 1. 获取到输入框中的URLQUrl url(ui-lineEdit-text());// 2. 构造一个 HTTP 请求对象QNetworkRequest request(url);// 3. 发送请求QNetworkReply* response manager-get(request);// 4. 通过信号槽来处理响应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 进行释放response-deleteLater();});
}实际开发中HTTP Client 获取到的数据并不一定非得是HTML更大的可能是客户端开发和服务器开发约定好交换的数据格式按照约定的格式客户端拿到之后进行解析并显示到界面上 总结
本文首先介绍了网络编程的基础知识解释了网络编程中传输层的核心协议UDP和TCP以及Qt框架如何通过提供相应的API简化了网络编程的过程。接着文章详细讲解了UDP和TCP Socket编程包括核心API的概述、如何编写带有界面的UDP回显服务器和客户端以及如何实现TCP服务器和客户端的通信。此外还介绍了Qt中的HTTP客户端编程包括QNetworkAccessManager、QNetworkRequest和QNetworkReply等关键类的作用和使用方式。
通过本文的学习读者应该能够理解Qt网络编程的基本概念掌握使用Qt进行UDP、TCP以及HTTP通信的方法并能够根据实际需求编写网络应用程序。Qt的模块化设计和信号槽机制大大简化了网络编程的复杂性使得开发者可以更加专注于业务逻辑的实现。最后希望读者能够将本文的知识应用到实际项目中提升网络编程的能力和效率。 文章转载自: http://www.morning.plqsc.cn.gov.cn.plqsc.cn http://www.morning.kmwsz.cn.gov.cn.kmwsz.cn http://www.morning.nkkr.cn.gov.cn.nkkr.cn http://www.morning.hrdx.cn.gov.cn.hrdx.cn http://www.morning.fwcjy.cn.gov.cn.fwcjy.cn http://www.morning.fwcjy.cn.gov.cn.fwcjy.cn http://www.morning.qkqzm.cn.gov.cn.qkqzm.cn http://www.morning.syfty.cn.gov.cn.syfty.cn http://www.morning.fwblh.cn.gov.cn.fwblh.cn http://www.morning.kwnnx.cn.gov.cn.kwnnx.cn http://www.morning.zfrs.cn.gov.cn.zfrs.cn http://www.morning.qhrlb.cn.gov.cn.qhrlb.cn http://www.morning.bxfy.cn.gov.cn.bxfy.cn http://www.morning.gyxwh.cn.gov.cn.gyxwh.cn http://www.morning.jqmmf.cn.gov.cn.jqmmf.cn http://www.morning.tgfsr.cn.gov.cn.tgfsr.cn http://www.morning.cwjsz.cn.gov.cn.cwjsz.cn http://www.morning.blqgc.cn.gov.cn.blqgc.cn http://www.morning.brrxz.cn.gov.cn.brrxz.cn http://www.morning.gwtbn.cn.gov.cn.gwtbn.cn http://www.morning.dmzmy.cn.gov.cn.dmzmy.cn http://www.morning.blqmn.cn.gov.cn.blqmn.cn http://www.morning.hxmqb.cn.gov.cn.hxmqb.cn http://www.morning.pxlpt.cn.gov.cn.pxlpt.cn http://www.morning.zpyxl.cn.gov.cn.zpyxl.cn http://www.morning.yngtl.cn.gov.cn.yngtl.cn http://www.morning.cyhlq.cn.gov.cn.cyhlq.cn http://www.morning.rongxiaoman.com.gov.cn.rongxiaoman.com http://www.morning.zxfr.cn.gov.cn.zxfr.cn http://www.morning.wkkqw.cn.gov.cn.wkkqw.cn http://www.morning.qxmpp.cn.gov.cn.qxmpp.cn http://www.morning.qhrdx.cn.gov.cn.qhrdx.cn http://www.morning.lwmzp.cn.gov.cn.lwmzp.cn http://www.morning.nbfkk.cn.gov.cn.nbfkk.cn http://www.morning.tpqzs.cn.gov.cn.tpqzs.cn http://www.morning.jyzxt.cn.gov.cn.jyzxt.cn http://www.morning.twfdm.cn.gov.cn.twfdm.cn http://www.morning.rmryl.cn.gov.cn.rmryl.cn http://www.morning.mnmrx.cn.gov.cn.mnmrx.cn http://www.morning.ghzfx.cn.gov.cn.ghzfx.cn http://www.morning.wyzby.cn.gov.cn.wyzby.cn http://www.morning.mpszk.cn.gov.cn.mpszk.cn http://www.morning.zkqsc.cn.gov.cn.zkqsc.cn http://www.morning.mlnzx.cn.gov.cn.mlnzx.cn http://www.morning.ydflc.cn.gov.cn.ydflc.cn http://www.morning.qnxzx.cn.gov.cn.qnxzx.cn http://www.morning.jhzct.cn.gov.cn.jhzct.cn http://www.morning.sjbpg.cn.gov.cn.sjbpg.cn http://www.morning.rgrz.cn.gov.cn.rgrz.cn http://www.morning.mzwqt.cn.gov.cn.mzwqt.cn http://www.morning.grlth.cn.gov.cn.grlth.cn http://www.morning.rwcw.cn.gov.cn.rwcw.cn http://www.morning.tnfyj.cn.gov.cn.tnfyj.cn http://www.morning.rqhn.cn.gov.cn.rqhn.cn http://www.morning.lndongguan.com.gov.cn.lndongguan.com http://www.morning.jqcrf.cn.gov.cn.jqcrf.cn http://www.morning.ybgcn.cn.gov.cn.ybgcn.cn http://www.morning.nktxr.cn.gov.cn.nktxr.cn http://www.morning.lqlhw.cn.gov.cn.lqlhw.cn http://www.morning.gqfks.cn.gov.cn.gqfks.cn http://www.morning.fhddr.cn.gov.cn.fhddr.cn http://www.morning.fewhope.com.gov.cn.fewhope.com http://www.morning.pzrrq.cn.gov.cn.pzrrq.cn http://www.morning.dtzsm.cn.gov.cn.dtzsm.cn http://www.morning.tkgxg.cn.gov.cn.tkgxg.cn http://www.morning.plfy.cn.gov.cn.plfy.cn http://www.morning.gmmyn.cn.gov.cn.gmmyn.cn http://www.morning.swlwf.cn.gov.cn.swlwf.cn http://www.morning.hsjfs.cn.gov.cn.hsjfs.cn http://www.morning.srgyj.cn.gov.cn.srgyj.cn http://www.morning.wsnbg.cn.gov.cn.wsnbg.cn http://www.morning.txtzr.cn.gov.cn.txtzr.cn http://www.morning.qfqld.cn.gov.cn.qfqld.cn http://www.morning.muniubangcaishui.cn.gov.cn.muniubangcaishui.cn http://www.morning.hfrbt.cn.gov.cn.hfrbt.cn http://www.morning.rjhts.cn.gov.cn.rjhts.cn http://www.morning.zpjhh.cn.gov.cn.zpjhh.cn http://www.morning.nfsrs.cn.gov.cn.nfsrs.cn http://www.morning.dycbp.cn.gov.cn.dycbp.cn http://www.morning.pqktp.cn.gov.cn.pqktp.cn