中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

做食品網(wǎng)站需要什么資質(zhì)中國新聞網(wǎng)發(fā)稿

做食品網(wǎng)站需要什么資質(zhì),中國新聞網(wǎng)發(fā)稿,網(wǎng)站制作程序,響應(yīng)式網(wǎng)站制作流程圖簡介: Netlink socket 是一種Linux特有的socket,用于實現(xiàn)用戶空間與內(nèi)核空間通信的一種特殊的進(jìn)程間通信方式(IPC) ,也是網(wǎng)絡(luò)應(yīng)用程序與內(nèi)核通信的最常用的接口。 Netlink 是一種在內(nèi)核和用戶應(yīng)用間進(jìn)行雙向數(shù)據(jù)傳輸?shù)姆浅:玫姆绞?a…

簡介:

????????Netlink socket 是一種Linux特有的socket,用于實現(xiàn)用戶空間內(nèi)核空間通信的一種特殊的進(jìn)程間通信方式(IPC) ,也是網(wǎng)絡(luò)應(yīng)用程序與內(nèi)核通信的最常用的接口。
????????Netlink 是一種在內(nèi)核和用戶應(yīng)用間進(jìn)行雙向數(shù)據(jù)傳輸?shù)姆浅:玫姆绞?#xff0c;用戶態(tài)應(yīng)用使用標(biāo)準(zhǔn)的 socket API 就能使用 Netlink 提供的強大功能,內(nèi)核態(tài)需要使用專門的內(nèi)核 API 來使用 Netlink。Netlink?的接口分為應(yīng)用層接口和內(nèi)核接口,我們需要在應(yīng)用程序?qū)崿F(xiàn)策略,然后在內(nèi)核實現(xiàn)機制。


用戶空間內(nèi)核空間的常用通信方式有三種:proc、ioctl、Netlink

(1) /proc-單向:虛擬文件系統(tǒng),用戶獲取內(nèi)核信息,輸出數(shù)據(jù)

(2) ioctl-單向:不能發(fā)送異步信息,用戶向內(nèi)核傳送命令

(3)netlink-雙向:kernel可以啟動傳輸,而不是僅限于響應(yīng)用戶空間請求而返回信息

1、netlink?優(yōu)點

  • 支持全雙工、異步通信
  • 用戶空間使用標(biāo)準(zhǔn)的socket接口即可進(jìn)行通信
  • 支持多播
  • 在內(nèi)核端可用于進(jìn)程上下文與中斷上下文

2、netlink常用場景

  • 獲取或修改路由信息
  • 監(jiān)聽TCP協(xié)議數(shù)據(jù)報文
  • 防火墻
  • netfilter子系統(tǒng)
  • 內(nèi)核事件向用戶態(tài)通知


一、netlink常用數(shù)據(jù)結(jié)構(gòu)及函數(shù)

1、netlink應(yīng)用層數(shù)據(jù)結(jié)構(gòu)及函數(shù)

網(wǎng)絡(luò)編程對比netlink:網(wǎng)絡(luò)編程中我們是使用?IP地址 + 端口號?進(jìn)行尋址的,而?netlink?則是通過?協(xié)議類型+進(jìn)程ID?進(jìn)行尋址的,其中?協(xié)議類型?會在調(diào)用?socket接口?的時候指定。

1.1 消息結(jié)構(gòu)

netlink中的message包含消息頭和消息體,消息頭占16字節(jié),后面跟的是消息體(數(shù)據(jù))。

  • Message Length:總長度,包括netlink消息頭在內(nèi)的總字節(jié)數(shù),占4字節(jié);
  • type:消息類型,往往用于協(xié)議流程。內(nèi)核定義了多個標(biāo)準(zhǔn)的消息類型。內(nèi)核已經(jīng)使用 netlink實現(xiàn)了多種協(xié)議,每個協(xié)議都有特定的類型和功能,占2字節(jié);
  • Flags:消息標(biāo)志,占2字節(jié);
  • Sequence number:序列號,該項是可選項,類似TCP協(xié)議中的報文號。占4字節(jié);
  • PID(port ID):端口號,發(fā)送端的端口ID號,占4字節(jié);
消息頭?nlmsghdr 結(jié)構(gòu)體:
struct nlmsghdr {__u32		nlmsg_len;	    /* 包括netlink消息頭在內(nèi),整個消息長度 */__u16		nlmsg_type;	    /* 消息類型 */__u16		nlmsg_flags;	/* 消息標(biāo)志 */__u32		nlmsg_seq;	    /* 消息報文的序列號 */__u32		nlmsg_pid;	    /* 發(fā)送端口的ID號,對于內(nèi)核來說該值就是0,對于用戶進(jìn)程來說就是其socket所綁定的ID號 */
};

1.2 netlink通信地址 struct sockaddr_nl

struct sockaddr_nl 是netlink通信地址跟普通socket struct sockaddr_in類似

struct sockaddr_nl {__kernel_sa_family_t    nl_family;  /* AF_NETLINK */unsigned short          nl_pad;     /* 目前未用到,填充為0 */__u32                   nl_pid;     /* port ID  (通信端口號),0表示發(fā)送給kernel*/__u32                   nl_groups;  /* 多播組掩碼 */
};

2、netlink內(nèi)核數(shù)據(jù)結(jié)構(gòu)及函數(shù)

2.1 常用宏

netlink消息類型及常用宏

/******************** netlink消息類型 ********************/
#define NETLINK_ROUTE       0   /* Routing/device hook              */
#define NETLINK_UNUSED      1   /* Unused number                */
#define NETLINK_USERSOCK    2   /* Reserved for user mode socket protocols  */
#define NETLINK_FIREWALL    3   /* Unused number, formerly ip_queue     */
#define NETLINK_SOCK_DIAG   4   /* socket monitoring                */
#define NETLINK_NFLOG       5   /* netfilter/iptables ULOG */
#define NETLINK_XFRM        6   /* ipsec */
#define NETLINK_SELINUX     7   /* SELinux event notifications */
#define NETLINK_ISCSI       8   /* Open-iSCSI */
#define NETLINK_AUDIT       9   /* auditing */
#define NETLINK_FIB_LOOKUP  10
#define NETLINK_CONNECTOR   11
#define NETLINK_NETFILTER   12  /* netfilter subsystem */
#define NETLINK_IP6_FW      13
#define NETLINK_DNRTMSG     14  /* DECnet routing messages */
#define NETLINK_KOBJECT_UEVENT  15  /* Kernel messages to userspace */
#define NETLINK_GENERIC     16
/* leave room for NETLINK_DM (DM Events) */
#define NETLINK_SCSITRANSPORT   18  /* SCSI Transports */
#define NETLINK_ECRYPTFS    19
#define NETLINK_RDMA        20
#define NETLINK_CRYPTO      21  /* Crypto layer */#define NETLINK_INET_DIAG   NETLINK_SOCK_DIAG#define MAX_LINKS 32/******************** netlink常用宏 ********************/
#define NLMSG_ALIGNTO   4U
/* 宏NLMSG_ALIGN(len)用于得到不小于len且字節(jié)對齊的最小數(shù)值 */
#define NLMSG_ALIGN(len) ( ((len)+NLMSG_ALIGNTO-1) & ~(NLMSG_ALIGNTO-1) )/* Netlink 頭部長度 */
#define NLMSG_HDRLEN     ((int) NLMSG_ALIGN(sizeof(struct nlmsghdr)))/* 計算消息數(shù)據(jù)len的真實消息長度(消息體 + 消息頭)*/
#define NLMSG_LENGTH(len) ((len) + NLMSG_HDRLEN)/* 宏NLMSG_SPACE(len)返回不小于NLMSG_LENGTH(len)且字節(jié)對齊的最小數(shù)值 */
#define NLMSG_SPACE(len) NLMSG_ALIGN(NLMSG_LENGTH(len))/* 宏NLMSG_DATA(nlh)用于取得消息的數(shù)據(jù)部分的首地址,設(shè)置和讀取消息數(shù)據(jù)部分時需要使用該宏 */
#define NLMSG_DATA(nlh)  ((void*)(((char*)nlh) + NLMSG_LENGTH(0)))/* 宏NLMSG_NEXT(nlh,len)用于得到下一個消息的首地址, 同時len 變?yōu)槭S嘞⒌拈L度 */
#define NLMSG_NEXT(nlh,len)  ((len) -= NLMSG_ALIGN((nlh)->nlmsg_len), \(struct nlmsghdr*)(((char*)(nlh)) + NLMSG_ALIGN((nlh)->nlmsg_len)))/* 判斷消息是否 >len */
#define NLMSG_OK(nlh,len) ((len) >= (int)sizeof(struct nlmsghdr) && \(nlh)->nlmsg_len >= sizeof(struct nlmsghdr) && \(nlh)->nlmsg_len <= (len))/* NLMSG_PAYLOAD(nlh,len) 用于返回payload的長度*/
#define NLMSG_PAYLOAD(nlh,len) ((nlh)->nlmsg_len - NLMSG_SPACE((len)))

2.2 常用函數(shù)

1)netlink_kernel_create

static inline struct sock *

netlink_kernel_create(struct net *net, int unit, struct netlink_kernel_cfg *cfg)

功能:創(chuàng)建內(nèi)核 socket,以提供和用戶態(tài)通信

參數(shù):

  • net: net指向所在的網(wǎng)絡(luò)命名空間namespace, 默認(rèn)情況傳入&init_net(不需要定義)這個全局變量;
  • unit:netlink協(xié)議類型,如NETLINK_TEST、NETLINK_SELINUX等;
  • cfg: cfg存放的是netlink內(nèi)核配置參數(shù)(如下)
struct netlink_kernel_cfg {unsigned int	groups;unsigned int	flags;void		(*input)(struct sk_buff *skb);    //input 回調(diào)函數(shù)struct mutex	*cb_mutex;int		(*bind)(struct net *net, int group);void		(*unbind)(struct net *net, int group);bool		(*compare)(struct net *net, struct sock *sk);
};

2)單播函數(shù) netlink_unicast()

int netlink_unicast(struct sock *ssk, struct sk_buff *skb, __u32 portid, int nonblock)

功能:發(fā)送單播消息

參數(shù):

  • ssk: netlink socket(netlink_kernel_create 的返回值);
  • skb: skb buff 指針;
  • portid: 通信的端口號;
  • nonblock:表示該函數(shù)是否為非阻塞,如果為1,該函數(shù)將在沒有接收緩存可利用時立即返回,而如果為0,該函數(shù)在沒有接收緩存可利用 定時睡眠;

3)多播函數(shù) netlink_broadcast()

int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, __u32 portid,
? ? ? ? ? ? ? ? ?__u32 group, gfp_t allocation)

功能:發(fā)送多播消息

參數(shù):

  • ssk: netlink socket(netlink_kernel_create 的返回值);
  • skb: 內(nèi)核skb buff;
  • portid: 端口id;
  • group: 是所有目標(biāo)多播組對應(yīng)掩碼的"OR"操作的合值;
  • allocation: 指定內(nèi)核內(nèi)存分配方式,通常GFP_ATOMIC用于中斷上下文,而GFP_KERNEL用于其他場合。這個參數(shù)的存在是因為該API可能需要分配一個或多個緩沖區(qū)來對多播消息進(jìn)行clone;


二、代碼實例

代碼示例分為用戶態(tài)內(nèi)核態(tài)netlink實現(xiàn)。

1、用戶態(tài)netlink程序

1.1?netlink應(yīng)用層基本步驟

(1) 使用 socket 聲明套接字

int socket(int domain, int type, int protocol)

  • domain:表示協(xié)議簇,在 netlink 中一般為 AF_NETLINK。
  • type:表示套接字類型,在 netlink 中一般為 SOCK_RAW。
  • protocol:表示協(xié)議類型,在 netlink 中可以是內(nèi)核支持的協(xié)議,也可以是自定義協(xié)議。

自定義協(xié)議例如:

    #define NETLINK_TEST 23    //自定義協(xié)議......int skfd = 0;skfd = socket(AF_NETLINK, SOCK_RAW, NETLINK_TEST);
(2)?使用?bind?綁定?本地地址?到套接字

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)? ? ? ? //綁定
?
/* sockaddr_nl 是 netlink 使用的地址數(shù)據(jù)結(jié)構(gòu),與網(wǎng)絡(luò)編程不同 */
struct sockaddr_nl {
? ? ?__kernel_sa_family_t??????nl_family; ?//一般為AF_NETLINK
? ? ?unsigned short????????????????nl_pad; ? ? //無需填充
? ? ?__u32? ? ? ? ? ? ? ? ? ? ? ? ? ? ? nl_pid; ? ? //與內(nèi)核通信的進(jìn)程的PID,0 則代表地址為內(nèi)核
? ? ?__u32? ? ? ? ? ? ? ? ? ? ? ? ? ? ? nl_groups; ?//多播組號,netlink支持多播
};

例如:

    struct sockaddr_nl nlsrc_addr = {0};/* 設(shè)置本地socket地址 */nlsrc_addr.nl_family = AF_NETLINK;nlsrc_addr.nl_pid = getpid();nlsrc_addr.nl_groups = 0;/* 綁定套接字 */if(bind(skfd, (struct sockaddr*)&nlsrc_addr, addr_len) != 0){printf("bind addr error\n");   return -1;}
(3) 構(gòu)造消息
(4) 接收/發(fā)送消息

netlink?有 2 套收發(fā)消息的接口,分別是?sendto/recvfrom、sendmsg/recvmsg。

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);

?

1.2 netlink用戶空間代碼

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <string.h>
#include <linux/netlink.h>#define NETLINK_TEST	17
#define RX_BUF_SIZE		100		//接收buf size
#define MAX_PLOAD		100		//發(fā)送message內(nèi)存sizetypedef struct
{struct nlmsghdr hdr;char msg[RX_BUF_SIZE];
}RX_KERNEL_MSG;int main(int argc, char* argv[])
{char *data = "This message is from user's space";//初始化struct sockaddr_nl src_addr, dest_addr;    //sockaddr_nl 是 netlink 使用的地址數(shù)據(jù)結(jié)構(gòu)int skfd, ret, rxlen = sizeof(struct sockaddr_nl);struct nlmsghdr *message;RX_KERNEL_MSG info;char *retval;/* 1.創(chuàng)建NETLINK socket */skfd = socket(PF_NETLINK, SOCK_RAW, NETLINK_TEST);if(skfd < 0){printf("can not create a netlink socket\n");return -1;}//初始化 netlink 源地址memset(&src_addr, 0, sizeof(src_addr));src_addr.nl_family = AF_NETLINK;src_addr.nl_pid = getpid();src_addr.nl_groups = 0;if(bind(skfd, (struct sockaddr *)&src_addr, sizeof(src_addr)) != 0){printf("bind() error\n");return -1;}//初始化 netlink 目標(biāo)地址memset(&dest_addr, 0, sizeof(dest_addr));dest_addr.nl_family = AF_NETLINK;dest_addr.nl_pid = 0;            //0表示發(fā)送給kerneldest_addr.nl_groups = 0;         //多播組/* 2.設(shè)置消息 */message = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PLOAD));memset(message, '\0', sizeof(struct nlmsghdr));message->nlmsg_len = NLMSG_SPACE(strlen(data)); //包括netlink消息頭在內(nèi),整個消息長度 message->nlmsg_flags = 0;            //消息標(biāo)志message->nlmsg_type = 0;             //消息類型message->nlmsg_seq = 0;              //消息報文的序列號message->nlmsg_pid = src_addr.nl_pid; //消息中加入本應(yīng)用端口pid,內(nèi)核應(yīng)答時往此pid寫入retval = memcpy(NLMSG_DATA(message), data, strlen(data));    //數(shù)據(jù)//    printf("User Send: %s, len:%d\r\n", (char *)NLMSG_DATA(message), message->nlmsg_len);/* 3.發(fā)送消息 */ret = sendto(skfd, message, message->nlmsg_len, 0,(struct sockaddr *)&dest_addr, sizeof(dest_addr));	//將message消息發(fā)送給內(nèi)核if(!ret){perror("send pid:");exit(-1);}/* 4.接收內(nèi)核發(fā)來的信息 */ret = recvfrom(skfd, &info, sizeof(RX_KERNEL_MSG), 0, (struct sockaddr*)&dest_addr, &rxlen);if(!ret){perror("recv form kerner:");exit(-1);}printf("User Receive ACK from kernel:%s\r\n",(char *)info.msg);//內(nèi)核和用戶進(jìn)行通信close(skfd);free((void *)message);return 0;
}

2、內(nèi)核空間代碼

2.1 netlink內(nèi)核態(tài)編程步驟

內(nèi)核接口與應(yīng)用層接口相似,其過程和使用的接口如下:

(1) 創(chuàng)建socket并注冊回調(diào)
struct netlink_kernel_cfg {unsigned int    groups;unsigned int    flags;void            (*input)(struct sk_buff *skb);    /* 接收回調(diào)函數(shù) */struct mutex    *cb_mutex;int             (*bind)(struct net *net, int group);void            (*unbind)(struct net *net, int group);bool            (*compare)(struct net *net, struct sock *sk);
};/* 創(chuàng)建接口,其中,參數(shù)net 一般為 &init_net */
static inline struct sock *netlink_kernel_create(struct net *net, int unit, struct netlink_kernel_cfg *cfg)/* 釋放接口 */
void netlink_kernel_release(struct sock *sk);
(2) 構(gòu)造消息?
//sk_buff 為內(nèi)核中 Netlink 使用的數(shù)據(jù)結(jié)構(gòu)體,下面分別是分配、使用、釋放的接口
static inline struct sk_buff *alloc_skb(unsigned int size, gfp_t priority)
static inline struct sk_buff *skb_get(struct sk_buff *skb)
void kfree_skb(struct sk_buff *skb);//下面為構(gòu)建消息內(nèi)容的接口
static inline struct nlmsghdr *nlmsg_put(struct sk_buff *skb, u32 portid, u32 seq, int type, int payload, int flags)

大概的調(diào)用方法為:?

//NLMSG_SPACE計算包括消息頭在內(nèi)的消息長度
size_t size = max(NLMSG_SPACE(message_size), (size_t)NLMSG_GOODSIZE);//分配sk_buff內(nèi)存
sk_buff * log_skb = alloc_skb(size, GFP_ATOMIC);//構(gòu)造消息結(jié)構(gòu)體
nlmsghdr *nlh = nlmsg_put(log_skb, /*pid*/0, /*seq*/0, type,message_size, 0);//將要發(fā)送的數(shù)據(jù)復(fù)制到消息結(jié)構(gòu)體上
if(payload != NULL) {memcpy(nlmsg_data(nlh),  payload, size);
}
(3) 接收/發(fā)送消息

發(fā)送消息有單播、廣播兩個接口,可以根據(jù)實際業(yè)務(wù)選擇使用。

int netlink_unicast(struct sock *ssk, struct sk_buff *skb, __u32 portid, int nonblock);
int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, __u32 portid, __u32 group, gfp_t allocation);

2.2 netlink內(nèi)核態(tài)模塊代碼

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <net/sock.h>
#include <linux/netlink.h>#define NETLINK_TEST    17struct {__u32 pid;
}user_process;static struct sock *netlinkfd = NULL;/* 發(fā)送到用戶空間 */
int send_to_user(int _pid, char *pbuf, uint16_t len)
{struct sk_buff *nl_skb;struct nlmsghdr *nlh;int ret;/* 創(chuàng)建sk_buff 空間 */nl_skb = nlmsg_new(len, GFP_ATOMIC);if(!nl_skb){printk("netlink alloc failure\n");return -1;}/* 設(shè)置netlink消息頭部 */nlh = nlmsg_put(nl_skb, 0, 0, NETLINK_TEST, len, 0);if(nlh == NULL){printk("nlmsg_put failaure \n");nlmsg_free(nl_skb);return -1;}/* 拷貝數(shù)據(jù)發(fā)送 */memcpy(nlmsg_data(nlh), pbuf, len);ret = netlink_unicast(netlinkfd, nl_skb, _pid, MSG_DONTWAIT);	//發(fā)送數(shù)據(jù)return ret;
}/* 接收回調(diào)函數(shù) */
static void netlink_rcv_msg(struct sk_buff *skb)
{struct nlmsghdr *nlh = NULL;char *data = NULL;char *kmsg = "hello users!!!";nlh = nlmsg_hdr(skb);if(skb->len >= NLMSG_SPACE(0)){data = NLMSG_DATA(nlh);    //數(shù)據(jù)if (data){user_process.pid = nlh->nlmsg_pid;    //數(shù)據(jù)從用戶端口ID獲取printk("kernel recv from user pid %d: %s\n", user_process.pid, data);send_to_user(user_process.pid, kmsg, strlen(kmsg));    //發(fā)送數(shù)據(jù)給用戶pid}} else {printk("%s: error skb, length:%d\n", __func__, skb->len);}
}struct netlink_kernel_cfg cfg = { .input  = netlink_rcv_msg, /* 設(shè)置接收回調(diào)函數(shù) */.groups = 0,.flags = 0,.cb_mutex = NULL,.bind = NULL,.compare = NULL,
};int __init test_netlink_init(void)
{/* 創(chuàng)建netlink socket */netlinkfd = (struct sock *)netlink_kernel_create(&init_net, NETLINK_TEST, &cfg);if(netlinkfd == NULL){printk(KERN_ERR "can not create a netlink socket\n");return -1;}return 0;
}void __exit test_netlink_exit(void)
{if (netlinkfd){netlink_kernel_release(netlinkfd); /* release ..*/netlinkfd = NULL;}printk(KERN_DEBUG "test_netlink_exit!!\n");
}module_init(test_netlink_init);
module_exit(test_netlink_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("donga");


3、測試結(jié)果

測試代碼下載鏈接:https://download.csdn.net/download/hinewcc/89590914

將內(nèi)核態(tài)代碼編譯成ko模塊,用戶態(tài)代碼編譯成app。insmod加載ko模塊,并運行app代碼:

$ insmod netlink_test.ko? ? ? ? #加載驅(qū)動

$ ./netlink_app? ? ? ? ? ? ? ? ? ? ? ?#運行APP

內(nèi)核態(tài)收到用戶態(tài)發(fā)送的數(shù)據(jù),并發(fā)送"hello users!!!"給用戶空間。

http://www.risenshineclean.com/news/60917.html

相關(guān)文章:

  • 好的做網(wǎng)站的域名服務(wù)器ip地址查詢
  • 為企業(yè)提供網(wǎng)站建設(shè)服務(wù)今日熱搜榜排名最新
  • 請問婚慶網(wǎng)站建設(shè)該怎么做呢保溫杯軟文營銷300字
  • 典型的b2b平臺有哪些成都百度提升優(yōu)化
  • 銅陵網(wǎng)站開發(fā)交換友情鏈接的注意事項
  • 中山做app網(wǎng)站公司河南網(wǎng)站排名優(yōu)化
  • canvas做的手機網(wǎng)站搜索引擎優(yōu)化指南
  • 建筑專業(yè)網(wǎng)站有哪些哪里能搜索引擎優(yōu)化
  • 扁平式風(fēng)格網(wǎng)站建站abc官方網(wǎng)站
  • 去年做啥網(wǎng)站能致富廣州中小企業(yè)seo推廣運營
  • 網(wǎng)站分站代理如何搭建一個自己的網(wǎng)站
  • 如何給公司網(wǎng)站做優(yōu)化網(wǎng)站推廣公司推薦
  • 哪里有做網(wǎng)站技術(shù)百度關(guān)鍵字
  • 金華大企業(yè)網(wǎng)站建設(shè)有哪些小說排行榜百度搜索風(fēng)云榜
  • wordpress主題修改ftp寧波seo網(wǎng)絡(luò)推廣
  • 謝崗鎮(zhèn)仿做網(wǎng)站網(wǎng)站排名優(yōu)化外包
  • 用動物做logo的旅游網(wǎng)站武漢網(wǎng)站推廣排名
  • 日照手機網(wǎng)站建設(shè)能翻到國外的瀏覽器
  • 石家莊市和城鄉(xiāng)建設(shè)局網(wǎng)站快手seo
  • 做北美市場用哪個網(wǎng)站成都網(wǎng)站排名 生客seo
  • 網(wǎng)站設(shè)計基本要求網(wǎng)絡(luò)營銷渠道策略研究
  • 網(wǎng)站做seo真的能帶來客戶嗎百度網(wǎng)盤官網(wǎng)下載
  • 網(wǎng)站域名后綴代表什么成都網(wǎng)站優(yōu)化排名
  • 網(wǎng)站信息可以邊建設(shè)邊組織正規(guī)優(yōu)化公司哪家好
  • 交錢做網(wǎng)站對方拿了錢不做該怎么辦網(wǎng)站維護(hù)工程師
  • 表格制作手機軟件seo關(guān)鍵詞推廣公司
  • 南寧大型網(wǎng)站推廣公司企業(yè)網(wǎng)站制作方案
  • 網(wǎng)站建設(shè)維護(hù)培訓(xùn)佛山seo外包平臺
  • 期末網(wǎng)站設(shè)計做什么網(wǎng)站比較好太原百度推廣開戶
  • 倉庫進(jìn)銷存管理軟件免費版搜索引擎優(yōu)化分析