站酷网app,福州网站设计软件公司,广州设计工作室集中地,开发公司合作协议一#xff0c;串口介绍
1.1 串口简介
串行接口简称串口#xff0c;也称串行通信接口或串行通讯接口#xff08;通常指COM接口#xff09;#xff0c;是采用串行通信方式的扩展接口#xff1b;
串行接口#xff08;SerialInterface#xff09;是指数据一位一位地顺序…一串口介绍
1.1 串口简介
串行接口简称串口也称串行通信接口或串行通讯接口通常指COM接口是采用串行通信方式的扩展接口
串行接口SerialInterface是指数据一位一位地顺序传送。其特点是通信线路简单只要一对传输线就可以实现双向通信可以直接利用电话线作为传输线从而大大降低了成本特别适用于远距离通信但传送速度较慢
1.2 串口使用场景
串口是一种用于android开发板对硬件设备通信的一种协议通过发送某种指令控制硬件设备通常用于物联网设备的信息传输比如切割器打印机ATM吐卡机、IC/ID卡读卡等。
1.3 波特率
波特率表示串口传输速率用来衡量数据传输的快慢即单位时间内载波参数变化的次数如每秒钟传送240个字符而每个字符格式包含10位1个起始位1个停止位8个数据位这时的波特率为240Bd比特率为10位*240个/秒2400bps。波特率与距离成反比波特率越大传输距离相应的就越短
1.4 数据位
这是衡量通信中实际数据位的参数。当计算机发送一个信息包实际的数据往往不会是8位的标准的值是6、7和8位。如何设置取决于你想传送的信息
1.5 停止位
用于表示单个包的最后一位。典型的值为11.5和2位。由于数据是在传输线上定时的并且每一个设备有其自己的时钟很可能在通信中两台设备间出现了小小的不同步。因此停止位不仅仅是表示传输的结束并且提供计算机校正时钟同步的机会。适用于停止位的位数越多不同时钟同步的容忍程度越大但是数据传输率同时也越慢
1.6 校验位
在串口通信中一种简单的检错方式。有四种检错方式偶、奇、高和低。当然没有校验位也是可以的。对于偶和奇校验的情况串口会设置校验位数据位后面的一位用一个值确保传输的数据有偶个或者奇个逻辑高位
1.7 串口地址
不同操作系统的串口地址Android是基于Linux的所以一般情况下使用Android系统的设备串口地址为/dev/ttyS0 /dev的串口包括虚拟串口真实串口USB转串口真实串口/dev/tty0..tty1这个一般为机器自带COM口虚拟串口/dev/ttyS1...ttyS2...ttyS3...均为虚拟console同样可以作为输入输出口USB转串口/dev/tty/USB0 二 Android中串口的实践
2.1 由于串口底层需要调用C代码所以需要用jni来进行C交互下面是全部的C代码以及JNI调用
2.1 SerialPort.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include jni.h
/* Header for class android_serialport_SerialPort */#ifndef _Included_android_serialport_SerialPort
#define _Included_android_serialport_SerialPort
#ifdef __cplusplus
extern C {
#endif
/** Class: android_serialport_SerialPort* Method: open* Signature: (Ljava/lang/String;IIIII)Ljava/io/FileDescriptor;*/
JNIEXPORT jobject JNICALL Java_android_serialport_SerialPort_open(JNIEnv *, jobject, jstring, jint, jint, jint, jint, jint);/** Class: android_serialport_SerialPort* Method: close* Signature: ()V*/
JNIEXPORT void JNICALL Java_android_serialport_SerialPort_close(JNIEnv *, jobject);#ifdef __cplusplus
}
#endif
#endif
/* Header for class android_serialport_SerialPort_Builder */#ifndef _Included_android_serialport_SerialPort_Builder
#define _Included_android_serialport_SerialPort_Builder
#ifdef __cplusplus
extern C {
#endif
#ifdef __cplusplus
}
#endif
#endif2.2 SerialPort.c
#include termios.h
#include unistd.h
#include sys/types.h
#include sys/stat.h
#include fcntl.h
#include string.h
#include jni.h#include SerialPort.h#include android/log.hstatic const char *TAG serial_port;
#define LOGI(fmt, args...) __android_log_print(ANDROID_LOG_INFO, TAG, fmt, ##args)
#define LOGD(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, TAG, fmt, ##args)
#define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, TAG, fmt, ##args)static speed_t getBaudrate(jint baudrate) {switch (baudrate) {case 0:return B0;case 50:return B50;case 75:return B75;case 110:return B110;case 134:return B134;case 150:return B150;case 200:return B200;case 300:return B300;case 600:return B600;case 1200:return B1200;case 1800:return B1800;case 2400:return B2400;case 4800:return B4800;case 9600:return B9600;case 19200:return B19200;case 38400:return B38400;case 57600:return B57600;case 115200:return B115200;case 230400:return B230400;case 460800:return B460800;case 500000:return B500000;case 576000:return B576000;case 921600:return B921600;case 1000000:return B1000000;case 1152000:return B1152000;case 1500000:return B1500000;case 2000000:return B2000000;case 2500000:return B2500000;case 3000000:return B3000000;case 3500000:return B3500000;case 4000000:return B4000000;default:return -1;}
}/** Class: android_serialport_SerialPort* Method: open* Signature: (Ljava/lang/String;II)Ljava/io/FileDescriptor;*/
JNIEXPORT jobject JNICALL Java_android_serialport_SerialPort_open(JNIEnv *env, jobject thiz, jstring path, jint baudrate, jint dataBits, jint parity,jint stopBits,jint flags) {int fd;speed_t speed;jobject mFileDescriptor;/* Check arguments */{speed getBaudrate(baudrate);if (speed -1) {/* TODO: throw an exception */LOGE(Invalid baudrate);return NULL;}}/* Opening device */{jboolean iscopy;const char *path_utf (*env)-GetStringUTFChars(env, path, iscopy);LOGD(Opening serial port %s with flags 0x%x, path_utf, O_RDWR | flags);fd open(path_utf, O_RDWR | flags);LOGD(open() fd %d, fd);(*env)-ReleaseStringUTFChars(env, path, path_utf);if (fd -1) {/* Throw an exception */LOGE(Cannot open port);/* TODO: throw an exception */return NULL;}}/* Configure device */{struct termios cfg;LOGD(Configuring serial port);if (tcgetattr(fd, cfg)) {LOGE(tcgetattr() failed);close(fd);/* TODO: throw an exception */return NULL;}cfmakeraw(cfg);cfsetispeed(cfg, speed);cfsetospeed(cfg, speed);cfg.c_cflag ~CSIZE;switch (dataBits) {case 5:cfg.c_cflag | CS5; //使用5位数据位break;case 6:cfg.c_cflag | CS6; //使用6位数据位break;case 7:cfg.c_cflag | CS7; //使用7位数据位break;case 8:cfg.c_cflag | CS8; //使用8位数据位break;default:cfg.c_cflag | CS8;break;}switch (parity) {case 0:cfg.c_cflag ~PARENB; //无奇偶校验break;case 1:cfg.c_cflag | (PARODD | PARENB); //奇校验break;case 2:cfg.c_iflag ~(IGNPAR | PARMRK); // 偶校验cfg.c_iflag | INPCK;cfg.c_cflag | PARENB;cfg.c_cflag ~PARODD;break;default:cfg.c_cflag ~PARENB;break;}switch (stopBits) {case 1:cfg.c_cflag ~CSTOPB; //1位停止位break;case 2:cfg.c_cflag | CSTOPB; //2位停止位break;default:cfg.c_cflag ~CSTOPB; //1位停止位break;}if (tcsetattr(fd, TCSANOW, cfg)) {LOGE(tcsetattr() failed);close(fd);/* TODO: throw an exception */return NULL;}}/* Create a corresponding file descriptor */{jclass cFileDescriptor (*env)-FindClass(env, java/io/FileDescriptor);jmethodID iFileDescriptor (*env)-GetMethodID(env, cFileDescriptor, init, ()V);jfieldID descriptorID (*env)-GetFieldID(env, cFileDescriptor, descriptor, I);mFileDescriptor (*env)-NewObject(env, cFileDescriptor, iFileDescriptor);(*env)-SetIntField(env, mFileDescriptor, descriptorID, (jint) fd);}return mFileDescriptor;
}/** Class: cedric_serial_SerialPort* Method: close* Signature: ()V*/
JNIEXPORT void JNICALL Java_android_serialport_SerialPort_close(JNIEnv *env, jobject thiz) {jclass SerialPortClass (*env)-GetObjectClass(env, thiz);jclass FileDescriptorClass (*env)-FindClass(env, java/io/FileDescriptor);jfieldID mFdID (*env)-GetFieldID(env, SerialPortClass, mFd, Ljava/io/FileDescriptor;);jfieldID descriptorID (*env)-GetFieldID(env, FileDescriptorClass, descriptor, I);jobject mFd (*env)-GetObjectField(env, thiz, mFdID);jint descriptor (*env)-GetIntField(env, mFd, descriptorID);LOGD(close(fd %d), descriptor);close(descriptor);
}
2.3 gen_SerialPort_h.sh 生成java的文件目录
#!/bin/sh
javah -o SerialPort.h -jni -classpath ../java android.serialport.SerialPort2.4 SerialPort.java jni对应的java文件
/** Copyright 2009 Cedric Priscal** Licensed under the Apache License, Version 2.0 (the License);* you may not use this file except in compliance with the License.* You may obtain a copy of the License at** http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an AS IS BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/package android.serialport;import android.util.Log;import androidx.annotation.NonNull;
import androidx.annotation.Nullable;import java.io.DataOutputStream;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;public final class SerialPort {private static final String TAG SerialPort;public static final String DEFAULT_SU_PATH /system/bin/su;private static String sSuPath DEFAULT_SU_PATH;private File device;private int baudrate;private int dataBits;private int parity;private int stopBits;private int flags;/*** Set the su binary path, the default su binary path is {link #DEFAULT_SU_PATH}** param suPath su binary path*/public static void setSuPath(Nullable String suPath) {if (suPath null) {return;}sSuPath suPath;}/*** Get the su binary path** return*/NonNullpublic static String getSuPath() {return sSuPath;}/** Do not remove or rename the field mFd: it is used by native method close();*/private FileDescriptor mFd;private FileInputStream mFileInputStream;private FileOutputStream mFileOutputStream;/*** 串口** param device 串口设备文件* param baudrate 波特率* param dataBits 数据位默认8,可选值为5~8* param parity 奇偶校验0:无校验位(NONE默认)1:奇校验位(ODD);2:偶校验位(EVEN)* param stopBits 停止位默认11:1位停止位2:2位停止位* param flags 默认0* throws SecurityException* throws IOException*/public SerialPort(NonNull File device, int baudrate, int dataBits, int parity, int stopBits,int flags) throws SecurityException, IOException {this.device device;this.baudrate baudrate;this.dataBits dataBits;this.parity parity;this.stopBits stopBits;this.flags flags;/* Check access permission */Log.e(TAG, SerialPort: canRead device.canRead());if (!device.canRead() || !device.canWrite()) {try {/* Missing read/write permission, trying to chmod the file */Process su;su Runtime.getRuntime().exec(sSuPath);String cmd chmod 666 device.getAbsolutePath() \n exit\n;su.getOutputStream().write(cmd.getBytes());if ((su.waitFor() ! 0) || !device.canRead() || !device.canWrite()) {throw new SecurityException();}} catch (Exception e) {e.printStackTrace();throw new SecurityException();}}mFd open(device.getAbsolutePath(), baudrate, dataBits, parity, stopBits, flags);if (mFd null) {Log.e(TAG, native open returns null);throw new IOException();}mFileInputStream new FileInputStream(mFd);mFileOutputStream new FileOutputStream(mFd);}/*** 串口默认的8n1** param device 串口设备文件* param baudrate 波特率* throws SecurityException* throws IOException*/public SerialPort(NonNull File device, int baudrate) throws SecurityException, IOException {this(device, baudrate, 8, 0, 1, 0);}/*** 串口** param device 串口设备文件* param baudrate 波特率* param dataBits 数据位默认8,可选值为5~8* param parity 奇偶校验0:无校验位(NONE默认)1:奇校验位(ODD);2:偶校验位(EVEN)* param stopBits 停止位默认11:1位停止位2:2位停止位* throws SecurityException* throws IOException*/public SerialPort(NonNull File device, int baudrate, int dataBits, int parity, int stopBits)throws SecurityException, IOException {this(device, baudrate, dataBits, parity, stopBits, 0);}// Getters and settersNonNullpublic InputStream getInputStream() {return mFileInputStream;}NonNullpublic OutputStream getOutputStream() {return mFileOutputStream;}/*** 串口设备文件*/NonNullpublic File getDevice() {return device;}/*** 波特率*/public int getBaudrate() {return baudrate;}/*** 数据位默认8,可选值为5~8*/public int getDataBits() {return dataBits;}/*** 奇偶校验0:无校验位(NONE默认)1:奇校验位(ODD);2:偶校验位(EVEN)*/public int getParity() {return parity;}/*** 停止位默认11:1位停止位2:2位停止位*/public int getStopBits() {return stopBits;}public int getFlags() {return flags;}// JNIprivate native FileDescriptor open(String absolutePath, int baudrate, int dataBits, int parity,int stopBits, int flags);public native void close();/*** 关闭流和串口已经try-catch*/public void tryClose() {try {mFileInputStream.close();} catch (IOException e) {//e.printStackTrace();}try {mFileOutputStream.close();} catch (IOException e) {//e.printStackTrace();}try {close();} catch (Exception e) {//e.printStackTrace();}}static {System.loadLibrary(serial_port);}public static Builder newBuilder(File device, int baudrate) {return new Builder(device, baudrate);}public static Builder newBuilder(String devicePath, int baudrate) {return new Builder(devicePath, baudrate);}public final static class Builder {private File device;private int baudrate;private int dataBits 8;private int parity 0;private int stopBits 1;private int flags 0;private Builder(File device, int baudrate) {this.device device;this.baudrate baudrate;}private Builder(String devicePath, int baudrate) {this(new File(devicePath), baudrate);}/*** 数据位** param dataBits 默认8,可选值为5~8* return*/public Builder dataBits(int dataBits) {this.dataBits dataBits;return this;}/*** 校验位** param parity 0:无校验位(NONE默认)1:奇校验位(ODD);2:偶校验位(EVEN)* return*/public Builder parity(int parity) {this.parity parity;return this;}/*** 停止位** param stopBits 默认11:1位停止位2:2位停止位* return*/public Builder stopBits(int stopBits) {this.stopBits stopBits;return this;}/*** 标志** param flags 默认0* return*/public Builder flags(int flags) {this.flags flags;return this;}/*** 打开并返回串口** return* throws SecurityException* throws IOException*/public SerialPort build() throws SecurityException, IOException {return new SerialPort(device, baudrate, dataBits, parity, stopBits, flags);}}public static void checkFilePermission(File file) {Log.e(TAG, canRead: file.canRead());Log.e(TAG, canWrite: file.canWrite());if (!file.canRead() || !file.canWrite()) {try {/* Missing read/write permission, trying to chmod the file */Process su;su Runtime.getRuntime().exec(sSuPath);String cmd chmod 7777 file.getAbsolutePath() \n exit\n;su.getOutputStream().write(cmd.getBytes());Log.e(TAG, checkFilePermission: file.getAbsolutePath());if ((su.waitFor() ! 0) || !file.canRead() || !file.canWrite()) {throw new SecurityException();}} catch (Exception e) {e.printStackTrace();Log.e(TAG, checkFilePermission: Exception: e.getMessage());throw new SecurityException();}}}//隐藏系统导航栏public void hideBottomNavation() {chmod(mount -o remount -w /system);chmod(chmod 777 /system);chmod(echo qemu.hw.mainkeys1 /system/build.prop);}public void chmod(String instruct) {try {Process process null;DataOutputStream os null;process Runtime.getRuntime().exec(su);os new DataOutputStream(process.getOutputStream());os.writeBytes(instruct);os.flush();os.close();} catch (Exception ex) {ex.printStackTrace();}}
}2.5 CMakeLists.txt编译c或c程序的规则文件 Cmake在Jni那篇讲过这个地方在讲下 CMake是一个可以跨平台的编译工具可以用简单的语句来描述所有平台的编译过程。他能够输出各种各样的 makefile 或者工程文件。和make与makefile类似我们在使用CMake时同样也需要一个文件来提供规则这个文件就是CMakeLists 使用CMake编写跨平台工程的流程如下 (1)编写源文件 (2)编写CMakeLists.txt (3)由CMake根据CMakeLists.txt来生成相应的makefile文件 (4)使用make并根据makefile调用gcc来生成相应的可执行文件。 # Sets the minimum version of CMake required to build your native library.
# This ensures that a certain set of CMake features is available to
# your build.cmake_minimum_required(VERSION 3.4.1)# Specifies a library name, specifies whether the library is STATIC or
# SHARED, and provides relative paths to the source code. You can
# define multiple libraries by adding multiple add.library() commands,
# and CMake builds them for you. When you build your app, Gradle
# automatically packages shared libraries with your APK.add_library( # Specifies the name of the library.serial_port# Sets the library as a shared library.SHARED# Provides a relative path to your source file(s).src/main/cpp/SerialPort.c )find_library( # Sets the name of the path variable.log-lib# Specifies the name of the NDK library that# you want CMake to locate.log )# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.target_link_libraries( # Specifies the target library.serial_port# Links the target library to the log library# included in the NDK.${log-lib} )2.5 调用串口-连接并获取输入输出流
Runnable serialConnectRunnable new Runnable() {Overridepublic void run() {try {if (mSerialPort null) {mSerialPort new SerialPort(new File(path), baudrate);mOutputStream mSerialPort.getOutputStream();mInputStream mSerialPort.getInputStream(); }} catch (SecurityException e) {ToastUtil.showToast(App.getInstance(), You do not have read/write permission to the serial port.);} catch (IOException e) {ToastUtil.showToast(App.getInstance(), The serial port can not be opened for an unknown reason.);} catch (InvalidParameterException e) {ToastUtil.showToast(App.getInstance(), Please configure your serial port first.);}//Serial结束}};2.6 读取串口消息 private class ReadThread extends Thread {Overridepublic void run() {super.run();while (!isInterrupted()) {int size;try {byte[] buffer new byte[512];if (mInputStream null) return;size mInputStream.read(buffer);if (size 0) {String mReceptionnew String(buffer, 0, size);String msg mReception.toString().trim();Log.e(TAG, 接收短消息 msg);}} catch (IOException e) {e.printStackTrace();return;}}}}2.7 发送串口指令 private class WriteRunnable implements Runnable {Overridepublic void run() {try {String cmdKZMT;;Log.e(TAG, 发送短消息 cmd);mOutputStream.write(cmd.getBytes());mOutputStream.flush();} catch (IOException e) {}}}2.8 断开关闭串口
/*** 关闭串口连接*/
public void closeSerialPortStream() {try {if (mOutputStream ! null) {mOutputStream.close();mOutputStream null;}if (mInputStream ! null) {mInputStream.close();mInputStream null;}if (mSerialPort ! null) {mSerialPort.close();mSerialPort null;}} catch (Exception e) {e.printStackTrace();}
}三 google官方串口工具类
3.1 除了上面自己编程C底层文件也可以直接用google官方的串口工具SDK(android-serialport-api)Github串口Demo地址:https://github.com/licheedev/Android-SerialPort-API
3.2 依赖
allprojects {repositories {...jcenter()mavenCentral() // since 2.1.3}
}dependencies {implementation com.licheedev:android-serialport:2.1.3
}3.3 使用
// 默认8N1(8数据位、无校验位、1停止位)
// Default 8N1 (8 data bits, no parity bit, 1 stop bit)
SerialPort serialPort new SerialPort(path, baudrate);// 可选配置数据位、校验位、停止位 - 7E2(7数据位、偶校验、2停止位)
// or with builder (with optional configurations) - 7E2 (7 data bits, even parity, 2 stop bits)
SerialPort serialPort SerialPort .newBuilder(path, baudrate)
// 校验位0:无校验位(NONE默认)1:奇校验位(ODD);2:偶校验位(EVEN)
// Check bit; 0: no check bit (NONE, default); 1: odd check bit (ODD); 2: even check bit (EVEN)
// .parity(2)
// 数据位,默认8可选值为5~8
// Data bit, default 8; optional value is 5~8
// .dataBits(7)
// 停止位默认11:1位停止位2:2位停止位
// Stop bit, default 1; 1:1 stop bit; 2: 2 stop bit
// .stopBits(2) .build();// read/write to serial port - needs to be in different thread!
InputStream in serialPort.getInputStream();
OutputStream out serialPort.getOutputStream();// close
serialPort.tryClose();四 总结
串口通讯使用到进程、Linux指令、JNI等但本质最终还是获得一个输入输出流去进行读写操作
串口通讯对于Android开发者来说仅需关注如何连接、操作(发送指令)、读取数据。
大部分的物联网通信本质上都是获取io流通过io流进行数据的传输和读取比如蓝牙wifi等只不过蓝牙wifi是通过Socket协议维持一个长连接进行通信 文章转载自: http://www.morning.mqbzk.cn.gov.cn.mqbzk.cn http://www.morning.tbplf.cn.gov.cn.tbplf.cn http://www.morning.pqcsx.cn.gov.cn.pqcsx.cn http://www.morning.ndltr.cn.gov.cn.ndltr.cn http://www.morning.smry.cn.gov.cn.smry.cn http://www.morning.lwjlj.cn.gov.cn.lwjlj.cn http://www.morning.klyyd.cn.gov.cn.klyyd.cn http://www.morning.tymwx.cn.gov.cn.tymwx.cn http://www.morning.ypxyl.cn.gov.cn.ypxyl.cn http://www.morning.sqnxk.cn.gov.cn.sqnxk.cn http://www.morning.bsqth.cn.gov.cn.bsqth.cn http://www.morning.qkgwx.cn.gov.cn.qkgwx.cn http://www.morning.smyxl.cn.gov.cn.smyxl.cn http://www.morning.wnjrf.cn.gov.cn.wnjrf.cn http://www.morning.pzjfz.cn.gov.cn.pzjfz.cn http://www.morning.gtbjf.cn.gov.cn.gtbjf.cn http://www.morning.txkrc.cn.gov.cn.txkrc.cn http://www.morning.cgmzt.cn.gov.cn.cgmzt.cn http://www.morning.jhrlk.cn.gov.cn.jhrlk.cn http://www.morning.mxdhy.cn.gov.cn.mxdhy.cn http://www.morning.fnczn.cn.gov.cn.fnczn.cn http://www.morning.qyrnp.cn.gov.cn.qyrnp.cn http://www.morning.ylph.cn.gov.cn.ylph.cn http://www.morning.rhkgz.cn.gov.cn.rhkgz.cn http://www.morning.sftrt.cn.gov.cn.sftrt.cn http://www.morning.xywfz.cn.gov.cn.xywfz.cn http://www.morning.cniedu.com.gov.cn.cniedu.com http://www.morning.atoinfo.com.gov.cn.atoinfo.com http://www.morning.jtjmz.cn.gov.cn.jtjmz.cn http://www.morning.lpsjs.com.gov.cn.lpsjs.com http://www.morning.ylqb8.cn.gov.cn.ylqb8.cn http://www.morning.wmqrn.cn.gov.cn.wmqrn.cn http://www.morning.gpmrj.cn.gov.cn.gpmrj.cn http://www.morning.nqbcj.cn.gov.cn.nqbcj.cn http://www.morning.sjpht.cn.gov.cn.sjpht.cn http://www.morning.lhhkp.cn.gov.cn.lhhkp.cn http://www.morning.lhrcr.cn.gov.cn.lhrcr.cn http://www.morning.rwzkp.cn.gov.cn.rwzkp.cn http://www.morning.zbkdm.cn.gov.cn.zbkdm.cn http://www.morning.dwyyf.cn.gov.cn.dwyyf.cn http://www.morning.tsxg.cn.gov.cn.tsxg.cn http://www.morning.vnuwdy.cn.gov.cn.vnuwdy.cn http://www.morning.dmcxh.cn.gov.cn.dmcxh.cn http://www.morning.rlsd.cn.gov.cn.rlsd.cn http://www.morning.21r000.cn.gov.cn.21r000.cn http://www.morning.xdwcg.cn.gov.cn.xdwcg.cn http://www.morning.rtbx.cn.gov.cn.rtbx.cn http://www.morning.wwsgl.com.gov.cn.wwsgl.com http://www.morning.cwjsz.cn.gov.cn.cwjsz.cn http://www.morning.pqwhk.cn.gov.cn.pqwhk.cn http://www.morning.rqkzh.cn.gov.cn.rqkzh.cn http://www.morning.rltsx.cn.gov.cn.rltsx.cn http://www.morning.bnrnb.cn.gov.cn.bnrnb.cn http://www.morning.flncd.cn.gov.cn.flncd.cn http://www.morning.rddlz.cn.gov.cn.rddlz.cn http://www.morning.dbrpl.cn.gov.cn.dbrpl.cn http://www.morning.pzrnf.cn.gov.cn.pzrnf.cn http://www.morning.htjwz.cn.gov.cn.htjwz.cn http://www.morning.nfgbf.cn.gov.cn.nfgbf.cn http://www.morning.fwzjs.cn.gov.cn.fwzjs.cn http://www.morning.njpny.cn.gov.cn.njpny.cn http://www.morning.mhpkz.cn.gov.cn.mhpkz.cn http://www.morning.rfhmb.cn.gov.cn.rfhmb.cn http://www.morning.httpm.cn.gov.cn.httpm.cn http://www.morning.rbxsk.cn.gov.cn.rbxsk.cn http://www.morning.nwljj.cn.gov.cn.nwljj.cn http://www.morning.pmjw.cn.gov.cn.pmjw.cn http://www.morning.ryjqh.cn.gov.cn.ryjqh.cn http://www.morning.dgxrz.cn.gov.cn.dgxrz.cn http://www.morning.ftwlay.cn.gov.cn.ftwlay.cn http://www.morning.nsyzm.cn.gov.cn.nsyzm.cn http://www.morning.fdsbs.cn.gov.cn.fdsbs.cn http://www.morning.mpsnb.cn.gov.cn.mpsnb.cn http://www.morning.ttaes.cn.gov.cn.ttaes.cn http://www.morning.saletj.com.gov.cn.saletj.com http://www.morning.hctgn.cn.gov.cn.hctgn.cn http://www.morning.kybyf.cn.gov.cn.kybyf.cn http://www.morning.nxkyr.cn.gov.cn.nxkyr.cn http://www.morning.ywrt.cn.gov.cn.ywrt.cn http://www.morning.ssmhn.cn.gov.cn.ssmhn.cn