基于WebServer工业数据采集项目

该项目通过CGI接口在WebServer与服务程序之间建立连接,利用多线程分别读取Modbus设备数据和处理服务请求。服务程序使用共享内存存储和交换数据,消息队列处理线圈状态变更。网页端通过按钮和文本框与CGI交互,实现数据的实时获取和设备控制。
摘要由CSDN通过智能技术生成

注:实训项目,仅为记录分享自己编写项目的历程和心得,无其他用途。

一.项目实现图解

         项目主要要解决的就是网页服务器WebServer和服务程序之间产生连接,为了达成连接,用到了“中间商”CGI,这是一个通用网关接口,通过这个CGI使网页服务器WebServer和服务程序之间可以相互解析,然后实现相应的要求。

二.项目实现详解

        可以分成三个方面详解:一方面是服务程序,第二方面CGI通用接口中对网页输入的内容和服务程序发送的内容的处理,第三方面是网页的制作,在网页中通过一定的操作可以获得相应的数据或者改变线圈的状态。

        1)服务程序

        在服务程序中,用到的是多线程,线程1用来循环读取Modbus设备的数据(相当于是03操作),把数据循环读入共享内存;线程2用来改变线圈的状态(相当于05操作),在消息队列中等待接受队列中的数据。

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include "modbus.h"
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <errno.h>
#include <string.h>
#include <sys/msg.h>

// 宏定义从机IP
#define IP 

// 线程传参结构体
struct keyword
{
    key_t key;
    modbus_t *ctx;
};

// 消息队列结构体
struct msgbuf
{
    long mtype;
    char msg_buf[32];
};

void *fun1(void *arg)
{
    struct keyword *k = (struct keyword *)arg;
    key_t key = k->key;
    modbus_t *ctx = k->ctx;

    // 2)创建或打开共享内存 shmget
    int shmid;
    shmid = shmget(key, 128, IPC_CREAT | IPC_EXCL | 0666);
    if (shmid < 0)
    {
        if (17 == errno)
        {
            shmid = shmget(key, 128, 0666);
        }
        else
        {
            perror("shmget err");
            return NULL;
        }
    }

    // 3)映射共享内存到用户空间 shmat
    char *p = shmat(shmid, NULL, 0);
    if (p == (char *)-1)
    {
        perror("shmat err");
        return NULL;
    }

    // 4.寄存器操作
    uint16_t dest1[32] = {0};
    int num1, num2;

    char buf[128] = {0};

    while (1)
    {
        // 功能码对应的函数  __03__
        num1 = modbus_read_registers(ctx, 0, 4, dest1);
        if (num1 < 0)
        {
            perror("modbus_read_registers err");
        }

        for (int i = 0; i < num1 / 3; i++)
        {
            // 把每一次的数据存到共享内存中
            sprintf(buf, "X:%d Y:%d Z:%d 光线传感器:%d", dest1[i], dest1[i + 1], dest1[i + 2], dest1[i + 3]);
            strcpy(p, buf);
            printf("%s\n", p); // 打印一下共享内存内容看一看

            sleep(1);
        }
    }
}

void *fun2(void *arg)
{
    struct keyword *k = (struct keyword *)arg;
    key_t key = k->key;
    modbus_t *ctx = k->ctx;

    // 2))创建或打开消息队列 msgget
    int msgid;
    msgid = msgget(key, IPC_CREAT | IPC_EXCL | 0666);
    if (msgid <= 0)
    {
        if (17 == errno)
        {
            msgid = msgget(key, 0666);
        }
        else
        {
            perror("msgget err");
            return NULL;
        }
    }

    while (1)
    {
        // 4))读取消息:可以按照类型将消息从消息队列中度走 msgrcv
        struct msgbuf val;
        msgrcv(msgid, &val, sizeof(val) - sizeof(long), 1, 0);

        printf("val.buf = %s\n", val.msg_buf);
        int a = (int)val.msg_buf[4] - 48;
        int b = (int)val.msg_buf[5] - 48;

        printf("a = %d  b = %d\n", a, b);
        
        // 功能码对应的函数  __05__
        modbus_write_bit(ctx, a, b);
        if (0 == a)
        {
            if (0 == b)
                printf("LED关\n");
            else
                printf("LED开\n");
        }
        else
        {
            if (0 == b)
                printf("蜂鸣器关\n");
            else
                printf("蜂鸣器开\n");
        }
    }
}

int main(int argc, char const *argv[])
{
    // 创建共享内存
    // 1)创建key值  ftok
    key_t key = 12138;
    // key = ftok(".", 'b');
    // if (key < 0)
    // {
    //     perror("ftok err");
    //     return -1;
    // }

    // 1.创建实例
    // modbus_new_tcp
    modbus_t *ctx = modbus_new_tcp(IP, 502);
    if (NULL == ctx)
    {
        perror("mod_new_tcp err ");
    }

    // 定义结构体变量并给结构体初始化
    struct keyword kkk;
    kkk.key = key;
    kkk.ctx = ctx;

    // 2.设置从机ID
    // modbus_set_slave
    int mss1 = modbus_set_slave(ctx, 1);
    if (mss1 < 0)
    {
        perror("modbus_set_slave err");
    }

    // 3.连接从机
    // modbus_connect
    int mc1 = modbus_connect(ctx);
    if (mc1 < 0)
    {
        perror("modbus_connect err");
    }

    // 创建线程1
    pthread_t tid1;
    if ((pthread_create(&tid1, NULL, fun1, &kkk)) != 0)
    {
        perror("pthread err\n");
        return -1;
    }
    printf("pthread success\n");

    // 创建线程2
    pthread_t tid2;
    if ((pthread_create(&tid2, NULL, fun2, &kkk)) != 0)
    {
        perror("pthread err\n");
        return -1;
    }
    printf("pthread success\n");

    // 等待回收线程2
    pthread_join(tid2, NULL);
    // 等待回收线程1
    pthread_join(tid1, NULL);

    // 5.关闭套接字
    // modbus_close
    modbus_close(ctx);
    // 6.释放实例
    // 	modbus_free
    modbus_free(ctx);

    return 0;
}

        2)CGI通用接口

        在CGI中,首先要判断要解析的功能,这里我用到了get(获取寄存器的数据)和set(改变线圈的状态)。

        当在网页发送get时,CGI接收到以后,打开共享内存,获取共享内存中的数据,然后给服务器回复,回复内容按照http协议格式,最后把读取的内容追加进去,然后发送给网页。

        当在网页发送set时,可以设定一定的格式,比如set=00,可以把内容直接放入消息队列,在服务程序端可以通过下标来获得需要的参数,用于改变线圈的状态。

int parse_and_process(char *input)

{

    char val_buf[2048] = {0};


    // 创建共享内存和消息队列

    // 1)创建key值  ftok

    key_t key = 12138;


    if (0 == strncmp(input, "get", 3))

    {

        // 2)创建或打开共享内存 shmget

        int shmid;

        shmid = shmget(key, 128, IPC_CREAT | IPC_EXCL | 0666);

        if (shmid < 0)

        {

            if (17 == errno)

            {

                shmid = shmget(key, 128, 0666);

            }

            else

            {

                perror("shmget err");

                return -1;

            }

        }


        // 3)映射共享内存到用户空间 shmat

        char *p = shmat(shmid, NULL, 0);

        if (p == (char *)-1)

        {

            perror("shmat err");

            return -1;

        }


        strcpy(val_buf, p);


        //数据处理完成后,需要给服务器回复,回复内容按照http协议格式

        char reply_buf[HTML_SIZE] = {0};


        sprintf(reply_buf, "%sContent-Length: %ld\r\n\r\n", HTML_HEAD, strlen(val_buf));

        strcat(reply_buf, val_buf);

        log_console("post json_str = %s", reply_buf);


        //向标准输出写内容(标准输出服务器已做重定向)

        fputs(reply_buf, stdout);


        // 4)撤销映射 shmdt

        shmdt(p);

    }

    else if (0 == strncmp(input, "set", 3))

    {

        // 2))创建或打开消息队列 msgget

        int msgid;

        msgid = msgget(key, IPC_CREAT | IPC_EXCL | 0666);

        if (msgid <= 0)

        {

            if (17 == errno)

            {

                msgid = msgget(key, 0666);

            }

            else

            {

                perror("msgget err");

                return -1;

            }

        }


        // 3))添加消息:按照类型将消息添加到已打开的消息队列末尾 msgsnd

        struct msgbuf val;

        val.mtype = 1;

        strcpy(val.msg_buf, input);


        log_console("msg_buf = %s\n", val.msg_buf);


        msgsnd(msgid, &val, sizeof(val) - sizeof(long), 0);


        strcpy(val_buf, input);


        // 判断并给网页回复消息(可不写)
        if ('0' == val_buf[4])

        {

            if ('1' == val_buf[5])

            {

                strcpy(val_buf, "LED开");

            }

            else

            {

                strcpy(val_buf, "LED关");

            }

        }

        else

        {

            if ('1' == val_buf[5])

            {

                strcpy(val_buf, "蜂鸣器开");

            }

            else

            {

                strcpy(val_buf, "蜂鸣器关");

            }

        }



        //数据处理完成后,需要给服务器回复,回复内容按照http协议格式

        char reply_buf[HTML_SIZE] = {0};


        sprintf(reply_buf, "%sContent-Length: %ld\r\n\r\n", HTML_HEAD, strlen(val_buf));

        strcat(reply_buf, val_buf);

        log_console("post json_str = %s", reply_buf);


        //向标准输出写内容(标准输出服务器已做重定向)

        fputs(reply_buf, stdout);

    }

        3)网页的制作

        制作要求:

        1.一个文本框,可以用来接收读取到的寄存器的数据,在网页中输出出来。

        2.一个按钮,通过点击按钮,实时刷新文本框中的数据。

        3.四个可单选的开关,控制线圈的状态。

        4.一个文本框,用来接收通过开关改变线圈后,显示线圈状态。

        通过下方代码<body></body>内的内容可以完成页面的制作要求:

         通过下方代码<body></body>内input中的onclick链接子函数,然后通过子函数执行相应的操作。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="js/xhr.js"></script>
    <script>
        function get_info() {
            // 获取标签为result的标签,赋值给v
            var v = document.getElementsByName("result");
            // v[0].value = "hello";   // 测试一下


            // 向服务器请求数据
            // 参数url:地址
            // data:请求数据正文
            // callback:回调函数,当服务器有数据回复时可以在回调函数中处理

            XHR.post('/cgi-bin/web.cgi', "get", function (x, info) {
                // console.log(info);   // info表示服务器回复的数据
                v[0].value = info;
            })
        }

        function func1(obj) {
            // 获取标签为bite1的标签,赋值给v
            var v = document.getElementsByName("result");

            // 向服务器请求数据
            // 参数url:地址
            // data:请求数据正文
            // callback:回调函数,当服务器有数据回复时可以在回调函数中处理
            if ('open' == obj) {
                XHR.post('/cgi-bin/web.cgi', "set=01", function (x, info) {
                    console.log(info);   // info表示服务器回复的数据
                    v[1].value = info;
                })
            }
            else {
                XHR.post('/cgi-bin/web.cgi', "set=00", function (x, info) {
                    console.log(info);   // info表示服务器回复的数据
                    v[1].value = info;
                })
            }
        }


        function func2(obj) {
            // 获取标签为bite1的标签,赋值给v
            var v = document.getElementsByName("result");

            // 向服务器请求数据
            // 参数url:地址
            // data:请求数据正文
            // callback:回调函数,当服务器有数据回复时可以在回调函数中处理
            if ('open' == obj) {
                XHR.post('/cgi-bin/web.cgi', "set=11", function (x, info) {
                    console.log(info);   // info表示服务器回复的数据
                    v[1].value = info;
                })
            }
            else {
                XHR.post('/cgi-bin/web.cgi', "set=10", function (x, info) {
                    console.log(info);   // info表示服务器回复的数据
                    v[1].value = info;
                })
            }
        }


    </script>
</head>

<body>
    <h1>基于WebServer的工业数据采集项目</h1>
    <br>
    数据:
    <input type="text" name="result" style="width: 300px" value="">
    <input type="button" name="command" value="get" onclick="get_info()">
    <br>
    <br>
    LED灯:
    开:<input type="radio" name="bit1" id="open" onclick="func1(id)">
    关:<input type="radio" name="bit1" id="close" onclick="func1(id)">
    <br>
    蜂鸣器:
    开:<input type="radio" name="bit2" id="open" onclick="func2(id)">
    关:<input type="radio" name="bit2" id="close" onclick="func2(id)">
    <br>
    结果:
    <input type="text" name="result" value="">
</body>

</html>

 

三.结果展示

        1.点击get按钮获取实时数据

        

         2.通过点击LED开的开关打开LED灯

        

         3.通过点击蜂鸣器开的开关打开蜂鸣器

        

         4.通过点击LED关的开关关闭LED灯

        

 

需要注意的问题:

        1.key值的确定,一定要认真的检查key值,确保在共享内存或者消息队列的key是相对应的,不然无法进行进程间通信。

        2.网页端给CGI发送的数据是一个字符串,比如字符串set=00,所以在改变线圈的状态时,需要考虑在传参时对字符串中的数据处理。

        3.网页制作的过程中,要注意LED灯和蜂鸣器的开和关两个开关的name相对应,不然就会产生可以同时选择的错误。

Bzboy_Beizhi9527
关注 关注
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
基于modbusWebServer工业数据采集系统
qq_53198674的博客
10-29 1060
通过modbus协议从网页端与服务器交互,服务器通过modbus来获取数据的一个采集系统
基于Webserver工业数据采集项目
qq_57999842的博客
07-05 528
数据采集
基于WebServer工业数据采集项目
weixin_45725380的博客
08-03 561
早期的Web服务器只能响应浏览器发来的http静态资源的请求,并将存储在服务器中的静态资源返回给浏览器。随着Web技术的发展,逐渐出现了动态技术,但是Web服务器并不能够直接运行动态脚本,为了解决Web服务器与外部应用程序之间数据互通,于是出现了CGI通用网关接口。简单理解,可以认为CGI是Web服务器和运行其上的应用程序进行“交流”的一种约定。CGI(Common Gateway Interface)通用网关接口,是外部扩展应用程序与 Web 服务器交互的一个标准接口。CGI特点。
项目--《基于Webserver工业数据采集
Mr_chench2241的博客
05-10 544
在main.c函数中通过handle_requst获取网页给服务器发送的数据中,请求头(环境变量)和请求正文(标准输入)信息,在函数中调用parse_and_process函数,在函数中根据请求正文判断网页需要执行什么操作(获取传感器数据还是控制硬件设备),根据请求完成数据采集和硬件控制,最终给网页回复(标准输出)数据(遵循http协议格式)LigHttpd是一个开源的轻量级嵌入式Web server,是提供一个专门针对高性能网站,安全、快速、兼容性好并且灵活的web server环境。
基于webserver工业数据采集
蜂蜂的博客
04-19 554
这是我学习lighttpd和cgi用来练手的项目,就是简单的完成在网页上可以完成对两个保持寄存器的读取,和写两个线圈。
基于WebServer工业数据采集项目(网页发出请求->网络服务器程序->modbus数据采集控制程序->slave(模拟设备
08-25
gcc day2progrom.c -o caiji -lmodbus -lpthread 编译modbus数据采集程序。 ./可执行文件名 windows下的ip 端口号(502,该端口号必须是这个) 如./caiji 192.168.0.140 502 第三步:进入到项目文件下的thttpd-master...
linux网络项目-基于WebServer工业数据采集项目
最新发布
05-21
在本Linux网络项目中,我们将探讨...总的来说,这个基于WebServer工业数据采集项目涵盖了从操作系统、网络通信、数据库管理到前后端开发的多个技术领域,需要综合运用多种技能来实现一个高效、安全且可靠的解决方案。
基于Webserver工业数据采集系统
qq_48520174的博客
04-20 847
本系统的设计流程大致如下:其中传感器模块和执行器模块使用Modbus slave软件代替。服务程序和从机之间的通信采用Modbus通信协议,因为Modbus协议是现在国内工业领域应用最多的协议,不仅仅用于PLC设备,还用于各种终端设备,如水表、电表、各种采集设备等等。其中Modbus通信协议有许多变种,最著名的三种版本有支持以太网的Modbus TCP,和支持串口的Modbus RTU、Modbus ASCII。
iss版本服务器读取_S7-1200 Modbus TCP服务器指令使用方法
weixin_39917894的博客
12-05 964
S7-1200 Modbus TCP 通信指令块 STEP 7 V13 SP1 软件版本中的Modbus TCP库指令目前最新的版本已升至V4.0,该版本的使用需要具备以下两个条件:1. 软件版本: STEP 7 V13 SP1及其以上2. 固件版本: S7-1200 CPU 的固件版本V4.1图1. Modbus TCP V4.0 版本指令块S7-1200 Modbus TCP 实验环境 下面以...
使用modbus协议读取云端数据
weixin_54435584的博客
12-26 784
Modbus协议是一种串行通信协议,是Modicon公司(现在的施耐德电气Schneider Electric)于1979年为使用可编程逻辑控制器(PLC)通信而发表的。Modbus协议是应用层协议,已经成为工业领域通信协议的业界标准,是工业电子设备之间常用的连接方式。Modbus是一个master/slave架构的协议,有一个节点是master节点,其他使用Modbus协 议参与通信的节点是slave节点,每一个slave设备都有一个唯一的地址。只有被指定为master节点的节点可以启动一个命令。
modbus数据采集通过http/websocket对外提供访问
nothing
02-23 1107
本软件是用go语言编写,可以运行在windows、linux等系统上,实现了通过modbus tcp采集modbus从站数据,对外提供http接口给用户查询实时数据和控制modbus地址写值,且还对外提供了websocket服务,用户可以直接通过websocket订阅实时变动更新的数据。DataType:数据类型, 0:bool,1:byte,2:word,3:dword,4:string,MbSlavePort: modbus从站(modbus服务器)的端口。Tag:给一个modbus地址取的别名。
工业物联网之从 ModbusWeb 数据可视化
chujing8951的博客
08-28 723
前言   工业物联网是一个范围很大的概念,本文从数据可视化的角度介绍了一个最小化的工业物联网平台,从 Modbus 数据采集到前端数据可视化呈现的基本实现思路。这里面主要涉及基于 Modbus 通讯规约的数据采集、后台实时数据处理、前端实时数据接收、前端实时数据可视化显示。物联网平台架构主要...
基于Modbus协议实现远程控制和数据检测
tangqinyuan的博客
02-15 1479
基于modbus协议控制设备和采集设备传感器数据
PHP通过soket发送modbus指令,如何通过modbus/TCP异步读取数据并发送到web
weixin_28829339的博客
03-22 878
我不熟悉modbus或pymodbus,所以我在猜测并留下很多空白供您填写。在这是从我最近放在一起用来接收snmptrap并将信息重新分发到连接的websockets上的东西。在希望这足以让你继续:#!/usr/bin/pythonfrom twisted.internet import protocol, reactor, utils, deferfrom twisted.web.server ...
第二节 使用ISM Web组态软件利用采集到的Modbus设备数据开发组态应用
一个爱好编程的怪兽
06-29 663
上一节我们已经通过ISM组态软件采集到了Modbus设备数据,这节我们就要利用这些数据开发组态利用。进入项目后,点击右侧的应用管理 然后点击创建应用。 点击确定后,创建应用。 找到我们刚才创建的应用,单击设计按钮,进入应用的开发界面 应用创建后,系统会默认创建一个867*765,背景为灰色的页面。 本节只是简单介绍了组态应用把采集的数据实时显示到页面上的步骤,系统还提......
利用modbus协议从云端服务器读取温湿度数据
apple_52030329的博客
12-25 2017
Modbus是一种广泛应用于工业控制领域串行通信协议,以其开放性、高可靠性、高效简单性、免费等优点,成为了工业领域通信协议的业界标准,是工业现场电子设备之间常用的连接方式。Modbus按其格式可分为,其中前两者适用于串行通信控制网络中,例如RS485,RS232等,而Modbus-TCP主要应用于基于以太网TCP/IP通信的控制网络中。通过此协议,控制器相互之间、或控制器和其它设备之间进行通信。Modbus协议使用的是主从通讯技术,即由主设备主动查询和操作从设备。一般将主控设备方所使用的协议称为。
Modbus tcp/ip 主站请求接收从站数据
guestpprro的专栏
10-17 6454
public class tcpModbus { public static void main(String[] args) { int port = Modbus.DEFAULT_PORT;   TCPMasterConnection con = null; // the connection   ModbusTCPTransaction trans = null; // th
低成本通用远程数据采集系统:基于单片机与Internet的实现
本篇论文研究了"基于INTERNET的远程数据采集系统",由张新卫等人提出,针对如何利用低成本技术实现控制系统的远程监控问题进行了探讨。该系统的核心思想是结合单片机(如凌阳16位单片机)与网络控制芯片,借助TCP/IP...
写文章

热门文章

  • Modbus TCP报文详解 5391
  • 电子词典(基于TCP协议多进程通信和数据库) 4636
  • 通过二叉树的前序,中序,后序,画出二叉树 2186
  • 使用STM32F407读写FM24CL64B-GTR驱动 532
  • 基于WebServer工业数据采集项目 442

最新评论

  • 通过二叉树的前序,中序,后序,画出二叉树

    2401_82437998: 解释好清晰!

  • 通过二叉树的前序,中序,后序,画出二叉树

    宁远133: 解释清晰,感谢大佬

  • 使用STM32F407读写FM24CL64B-GTR驱动

    HelloKQing: 有用的贴纸,测试下来FM24V02A也能直接表情包使用

  • 基于WebServer工业数据采集项目

    CSDN-Ada助手: 恭喜你写了第三篇博客!标题“基于WebServer工业数据采集项目”听起来很有实际应用价值。你的持续创作精神值得赞赏。在下一篇博客中,或许你可以分享一些关于如何优化数据采集过程或者介绍一些常见的工业数据采集项目案例。谦虚地说,我相信你的经验和见解将会给读者带来更多的启发和帮助。期待你的下一篇博客! CSDN 正在通过评论红包奖励优秀博客,请看红包流:https://bbs.csdn.net/?type=4&header=0&utm_source=csdn_ai_ada_blog_reply3

  • 电子词典(基于TCP协议多进程通信和数据库)

    CSDN-Ada助手: 恭喜你写了第四篇博客!标题听起来很有趣,我对基于TCP协议多进程通信和数据库的电子词典很感兴趣。你的创作内容一直都很有深度和技术性,让我从中受益匪浅。希望你能继续保持创作的热情和努力,为我们带来更多有关技术和应用的精彩博客。接下来,我建议你可以探索一些实际案例,分享一些电子词典在现实生活中的应用场景,这样读者能更好地理解它的价值和实用性。期待你的下一篇作品! CSDN 会根据你创作的前四篇博客的质量,给予优秀的博主博客红包奖励。请关注 https://bbs.csdn.net/forums/csdnnews?typeId=116148&utm_source=csdn_ai_ada_blog_reply4 看奖励名单。

大家在看

  • 智慧云党建”主题网站设计与实现(源码+定制+开发) 454
  • 大学生入学审核系统(论文+源码)_kaic 865
  • Java爬虫:获取商品销量详情API返回值的实战指南
  • 【K8s】专题十四(2):Kubernetes 安全机制之 Security Context 1131
  • 普通人该如何入门大模型?(附AI大模型资源)

最新文章

  • 使用STM32F407读写FM24CL64B-GTR驱动
  • 电子词典(基于TCP协议多进程通信和数据库)
  • Modbus TCP报文详解
2024年1篇
2023年4篇

目录

目录

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

深圳坪山网站建设公司义马优化网站建设汉中网站优化排名咨询怎么样进行网站优化怎么做新乡知名网站优化哪家好网站过度优化的几个误区对网站的优化现状分析完整的网站优化流程沙头网站优化哪个好山东网站关键词排名优化技巧自己的网站怎么样推广优化网站域名优化极品易.速达英文网站的优化怎么优化网站排名关键词龙海网站的优化遵化市网站关键词优化如何优化网站里择火星赞高陵网站推广优化公司精准网站优化技巧东阿县优化网站商务类网站优化井陉矿区个人网站优化答疑解惑传统网站推广优化如何优化网站抉择火14星重庆靠谱的电商网站优化简阳网站优化天长网站seo优化揭阳网站改版优化莱山个性化网站优化济南建材行业网站优化推广技巧网站的优化只信j火9星好棒香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声卫健委通报少年有偿捐血浆16次猝死汪小菲曝离婚始末何赛飞追着代拍打雅江山火三名扑火人员牺牲系谣言男子被猫抓伤后确诊“猫抓病”周杰伦一审败诉网易中国拥有亿元资产的家庭达13.3万户315晚会后胖东来又人满为患了高校汽车撞人致3死16伤 司机系学生张家界的山上“长”满了韩国人?张立群任西安交通大学校长手机成瘾是影响睡眠质量重要因素网友洛杉矶偶遇贾玲“重生之我在北大当嫡校长”单亲妈妈陷入热恋 14岁儿子报警倪萍分享减重40斤方法杨倩无缘巴黎奥运考生莫言也上北大硕士复试名单了许家印被限制高消费奥巴马现身唐宁街 黑色着装引猜测专访95后高颜值猪保姆男孩8年未见母亲被告知被遗忘七年后宇文玥被薅头发捞上岸郑州一火锅店爆改成麻辣烫店西双版纳热带植物园回应蜉蝣大爆发沉迷短剧的人就像掉进了杀猪盘当地回应沈阳致3死车祸车主疑毒驾开除党籍5年后 原水城县长再被查凯特王妃现身!外出购物视频曝光初中生遭15人围殴自卫刺伤3人判无罪事业单位女子向同事水杯投不明物质男子被流浪猫绊倒 投喂者赔24万外国人感慨凌晨的中国很安全路边卖淀粉肠阿姨主动出示声明书胖东来员工每周单休无小长假王树国卸任西安交大校长 师生送别小米汽车超级工厂正式揭幕黑马情侣提车了妈妈回应孩子在校撞护栏坠楼校方回应护栏损坏小学生课间坠楼房客欠租失踪 房东直发愁专家建议不必谈骨泥色变老人退休金被冒领16年 金额超20万西藏招商引资投资者子女可当地高考特朗普无法缴纳4.54亿美元罚金浙江一高校内汽车冲撞行人 多人受伤

深圳坪山网站建设公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化