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

电子商务网站建设和维护做一件代发的网站

电子商务网站建设和维护,做一件代发的网站,wordpress 首页 404,有哪些做app的网站第三十三章基于lwip的tftp server实验 文件传输是网络环境中的一项基本应用#xff0c;其作用是将一台电子设备中的文件传输到另一台可能相距很远的电子设备中。TFTP作为TCP/IP协议族中的一个用来在客户机与服务器之间进行文件传输的协议#xff0c;常用于无盘工作站、路由器…第三十三章基于lwip的tftp server实验 文件传输是网络环境中的一项基本应用其作用是将一台电子设备中的文件传输到另一台可能相距很远的电子设备中。TFTP作为TCP/IP协议族中的一个用来在客户机与服务器之间进行文件传输的协议常用于无盘工作站、路由器以及远程测控设备从主机上获取引导配置文件实现远程升级。由于TFTP简单且易实现本实验我们使用lwip协议栈实现TFTP Server的功能。本章包括以下几个部分 3333.1简介 33.2实验任务 33.3硬件设计 33.4软件设计 33.5下载验证 33.1简介 一、TFTP简介基于RFC1350版本 简单文件传输协议TFTP (Trivial File Transfer Protocol) 是TCP/IP协议族中的一个用来在客户机与服务器之间进行简单文件传输基于UDP实现的应用层协议提供不复杂、开销不大的文件传输服务端口号为 69。为了保证文件可靠传输TFTP有自己的差错改正措施。TFTP 只支持文件传输、不支持交互、没有庞大的命令集也没有目录列表功能以及不能对用户进行身份鉴别。 与常用的文件传送协议 FTP (File Transfer Protocol) 相比FTP基于TCP协议提供交互式的访问允许客户指明文件的类型与格式、允许执行对目录和文件的访问并且可以完成特定类型的目录操作以及需要进行身份验证。 可以说FTP是完整的、面向会话、常规用途的文件传输协议而TFTP相当于用作特殊目的简化版的FTP。 TFTP的主要优点有两个。 第一TFTP可用于UDP环境。例如当需要将程序或文件同时向许多机器下载时就往往需要使用TFTP。 第二TFTP代码所占的内存较小。这对较小的计算机或某些特殊用途的设备如无盘工作站等是很重要的。这些设备不需要硬盘只需要固化了TFTP、UDP和IP的小容量只读存储器即可。当接通电源后设备执行只读存储器中的代码在网络上广播一个TFTP请求。网络上的TFTP服务器就发送响应其中包括可执行二进制程序。设备收到此文件后将其放入内存然后开始运行程序。这种方式增加了灵活性也减少了开销。 TFTP的主要特点如下 1每次传送的数据报文中有512字节的数据但最后一次可不足512字节。 2数据报文按序编号从1开始。 3支持ASCII码或二进制传送。 4可对文件进行读或写。 5使用很简单的首部。 6实现简单而不是高的系统吞吐量 二、TFTP的五种报文 TFTP的报文格式如图 34.1.1所示可以看到TFTP有五种报文每种报文有不同的操作码这五种报文分别是RRQ、WRQ、DATA、ACK和ERROR报文。下面我们简单的介绍下这五种报文。 RRQ/WRQ报文 模式字段中包含两种字符串中的一种netascii表示ASCII文件octet表示二进制文件。对于RRQ客户向TFTP服务器发送读请求后服务器返回一个块编号为1的DATA报文。而对于WRQ客户向TFTP服务器发送写请求后服务器返回的是块编号为1的ACK报文。总之不管是RRQ还是WRQ接收DATA数据的一方发送ACK确认而发送DATA数据的一方只负责发送数据。 图 34.1.1 TFTP报文格式 a)DATA报文 发送方用于传送数据块。所有的块都用数字顺序编码从1开始。在所有的DATA报文中这个块必须准确地等于512Byte但最后一个块可以小于或等于512Byte。当发送的DATA报文中数据部分的长度小于512Byte表示DATA报文发送完毕所以小于数据部分512Byte的DATA数据报可以作为文件结束的标志。特殊的情况是当文件中的数据正好是512Byte的整数倍时那么发送端必须再发送一个具有数据部分为0Byte的额外的DATA数据块以表示传输的结束。数据可以采用ASCII码或二进制来传送。 b)ACK报文 块号表示它所收到的块号不是下一个期待的块号这与TCP中的ACK序号不同。特殊情况是当客户向服务器发送一个WRQ请求后服务器返回给客户的是一个块号为0的ACK报文表示服务器已经准备好了接收来自客户的数据报。 c)EEROR报文差错报文 ERROR报文既可以由客户发送也可以由服务器发送当一条连接如读连接或写连接不能建立或在数据传输中出现问题时使用。差错码定义了差错的类型差错信息是一个可变字节包含原文中的差错数据。 从上面的报文格式中可以看出TFTP报文没有差错检验和字段所以接收端检验数据是否出现差错的唯一方法是通过该TFTP数据报的UDP首部中的检验和字段。 三、TFTP传输过程 以TFTP客户端向 TFTP 服务器发送写请求为例说明整个过程。 1)服务器使用默认端口号69被动打开连接 2)客户主动打开连接向服务器进程发送WRQ报文报文中包含写入文件的文件名 3)TFTP服务器进程选择一个新的端口和TFTP客户进程进行通信并向TFTP客户进程发送块编号为0的的ACK报文 4)客户端收到服务器的ACK报文后发送DATA报文数据段为512Byte少于512Byte表明是文件的最后的数据块编号逐次递增 5)TFTP服务器校验收到的DATA报文的块编号如果校验正确则将数据写入文件并发送ACK报文表明已接收到数据ACK报文的块编号为本次接收的DATA报文的块编号。另外还判断数据段长度是否小于512 Byte小于则表明文件传输完成关闭连接如果等于512Byte则重复步骤4-5直到所有请求的数据发送完毕。 从上面的传输过程可以看出TFTP 是一种类似于停止等待协议不是真正的停止等待协议在停止等待协议中接收方发送的 ack 表示期望收到的下一个分组而在 TFTP 的 ACK 报文中ACK的块号表示的是本次成功收到的数据块而不是下一个期望的下一个数据块。TFTP 客户端只有收到服务器的确认报文ACK后才会接着向服务器发送新的数据。 另外需要注意的是TFTP 协议中用于读文件的连接和用于写文件的连接的建立方式不同建立读连接的时候客户首先向服务器发送 RRQ 读报文服务器收到该报文后直接发回给该客户 DATA 报文并且包含第一个数据块块号为 1。而建立写连接的时候客户首先先服务器发送 WRQ 写报文服务器收到该报文后则发回给客户 ACK 报文使用的块号为 0当然上面两种情况如果遇到请求报文出错时均会发回 ERROR 报文作为响应。 33.2实验任务 本章的实验任务是使用LWIP协议栈搭建TFTP服务器PC电脑上的客户端可以从TFTP服务器读取文件也可向TFTP服务器写入文件文件存放在SD卡中。 33.3硬件设计 根据实验任务我们可以画出本次实验的系统框图如下图所示 图 34.3.1 系统框图 在图 34.3.1中UART用于打印程序相关的信息LWIP通过以太网传输数据TF卡用于存放文件包括服务器创建的文件和客户端写入的文件。 step1创建Vivado工程 本次实验的硬件设计可以在《lwip echo server》实验的基础上添加SD卡。 1-1 我们先打开《lwip echo server》实验的Vivado工程打开后将工程另存为“lwip_tftp_server”工程然后点击“OK”按钮。 step2使用IP Integrator创建Processing System 2-1 在Vivado界面左侧的Flow Navigator中点击IP INTEGRATOR下的Open Block Design以打开Diagram窗口。 2-2 在打开的下图Diagram窗口双击打开Zynq UltraScale MPSOC重定义窗口。 图 34.3.2 重定义Zynq UltraScale MPSOC 2-3 在下图所示的重定义窗口如同《SD卡读写TXT文本实验》那样配置SD卡。点击左侧的I/O Configuration在右侧的界面中找到SD卡控制器配置选项并勾选“SD1”Slot Type选择SD2.0然后选择MIO46…51并勾选CD选项然后点击“OK”如下图所示。 图 34.3.3 SD卡接口配置界面 2-4 由于不需要添加其它IP点击Validate Design验证成功后按CtrlS快捷键保存Diagram。此时我们的第二步完成进入第三步 step3生成顶层HDL 在sources面板中右键点击Block Design设计文件“design_1.bd”然后执行“Generate Output Products”。 step4生成Bitstream文件并导出到VITIS 由于本实验未用到PL部分所以无需生成Bitstream文件只需导出Hardware硬件平台文件即可。如果使用到PL则需要添加引脚约束以及对该系统进行综合、实现并生成Bitstream文件。 4-1 导出硬件。 在菜单栏中选择 File Export Export hardware。注意导出路径的选择并取消勾选“Include bitstream”然后点击“OK”按钮。 新建vitis文件夹将导出的平台文件移动到该文件夹下。 4-2 硬件导出完成后选择菜单Tools-Launch Vitis指定工作空间启动Vitis开发环境。 33.4软件设计 下面我们开始第五步——创建应用工程。 step5在Vitis中创建应用工程 5-1在菜单栏中选择“File-New-Application Project”, 在弹出的界面中输入工程名“lwip_tftp_server”点击“Next ”添加应用平台文件添加完成后接下来依次点击“Next”直到弹出选择模板界面选择“Empty Application”空应用工程然后点击“Finish”按钮。 5-2 设置板级支持包(BSP)。 打开板级支持包设置界面具体步骤可参考前面的实验。在弹出的BSP设置界面勾选“lwip212”和“xilffs”以启用lwip和文件系统如图 34.4.1所示。 如果没有开启DHCP服务可以开启DHCP服务点击standalone下的lwip212在右侧界面中到“dhcp_options”将其下的两个选项的“Value”设置为“true”如图 34.4.2所示。 图 34.4.1 BSP的设置界面 图 34.4.2 开启DHCP 5-3 由于Xilinx提供的lwip例程里有tftp server的源代码所以我们无需自己手动编写直接添加即可。 双击硬件平台工程design_1_wrapper下的platform.spr在打开的界面中单击standalone on psu_cortexa53_0下的Board Support Package然后展开Libraries。可以看到Libraries标题下有lwip211和xilffs两个库单击lwip211库后的“Import Example”选项如下图所示。 图 34.4.3 Import lwip Example 5-4 在弹出的下图所示界面中点击下方的“Examples Directory”。 图 34.4.4打开例程文件目录 5-5 打开例程所在文件的目录里面有Xilinx关于lwip的全部例程源文件。我们选择本次实验需要的源文件如图 34.4.5所示并单击鼠标右键选择复制。复制完成后关闭该目录并在打开的图 34.4.4界面中点击“Cancel”退出。 图 34.4.5 例程所在文件的目录 5-6 单击Vitis软件的lwip_tftp_server/src目录按下粘贴快捷键“Ctrl-v”将复制的文件粘贴到该src目录下如下图所示。 图 34.4.6 src目录 5-7 为了方便分析我们将刚才复制到src目录的源文件重命名主要是删除不需要的前缀其中“lwip_example_tftpserver_common.h”改为“lwip_tftp_server.h”然后进行编译如下图所示 图 34.4.7 删除不相关前缀后的src文件夹内容 5-8 现在我们打开main.c文件为了方便分析源代码在main.c文件中将带有下图箭头所指的预编译指令删除。 图 34.4.8 删除不需要的预编译指令 删除不适用的预编译指令后的main.c代码与我们《lwip echo server实验》的main.c代码基本相同区别在于本次TFTP server实验没有使用IPv6所以没有IPv6的预编译指令其他完全相同main.c代码讲解见《lwip echo server实验》。 5-9本实验可以说是在《lwip echo server实验》的基础上增加了文件系统然后将Echo server的实现文件echo.c文件改写成了TFTP Server的实现文件。因而本实验的主要代码是TFTP Server的实现该实现在lwip_tftp_server.h和lwip_tftp_server.c中由于这两个文件的总代码有500多行因此我们挑选部分代码进行讲解。此处以客户端写文件为例讲解lwip_tftp_server.c中的写文件实现源码。讲解以函数调用顺序进行。 首先我们看main函数中调用的start_application函数该函数实现如下 352 void start_application() 353 { 354 struct udp_pcb *pcb; 355 err_t err; 356 357 //创建测试文件用于客户端读取 358 err tftp_create_test_file(); 359 if (err) { 360 xil_printf(Unable to create test file\r\n); 361 return; 362 } 363 364 //创建新的UDP PCB 365 pcb udp_new(); 366 if (!pcb) { 367 xil_printf(Error creating PCB. Out of Memory\r\n); 368 return; 369 } 370 371 //绑定端口 372 err udp_bind(pcb, IP_ADDR_ANY, TFTP_PORT); 373 if (err ! ERR_OK) { 374 xil_printf(Unable to bind to port %d; err %d\r\n, 375 TFTP_PORT, err); 376 udp_remove(pcb); 377 return; 378 } 379 380 //设置接收回调函数 381 udp_recv(pcb, (udp_recv_fn) tftp_server_recv_cb, NULL); 382 }可以看到该函数首先通过调用tftp_create_test_file函数创建了测试文件用于tftp客户端读取tftp服务器的文件数据测试文件名为sample#.txt其中“#”为数字1、2、3中的任一值其文件内容为“----- This is a test file for TFTP server application -----”。如果不执行客户端的读取文件请求可删除该函数的调用及其实现。 由于TFTP基于UDP协议从start_application函数可以看到lwip中使用UDP协议很简单。首先通过udp_new函数创建一个新的UDP PCB然后调用udp_bind函数绑定端口号IP_ADDR_ANY表明为任意本地地址TFTP_PORT是在lwip_tftp_server.h宏定义的端口号其值为69即TFTP的默认端口。最后调用udp_recv函数设置接收回调函数就完成了UDP服务的创建服务端的功能即TFTP协议由回调函数实现。回调函数代码如下 270 static void tftp_server_recv_cb(void *arg, struct udp_pcb *upcb, struct pbuf *p, 271 ip_addr_t *ip, u16_t port) 272 { 273 tftp_opcode op tftp_get_opcode(p-payload); 274 char fname[512]; 275 struct udp_pcb *pcb; 276 err_t err; 277 278 pcb udp_new(); 279 if (!pcb) { 280 xil_printf(Error creating PCB. Out of Memory\r\n); 281 goto cleanup; 282 } 283 284 //绑定到端口0以接收下一个可用的空闲端口 285 err udp_bind(pcb, IP_ADDR_ANY, 0); 286 if (err ! ERR_OK) { 287 xil_printf(Unable to bind to port %d; err %d\r\n, port, err); 288 goto cleanup; 289 } 290 291 switch (op) { 292 case TFTP_RRQ: 293 //从payload中获取文件名 294 strcpy(fname, p-payload FIL_NAME_OFFSET); 295 printf(TFTP RRQ (read request): %s\r\n, fname); 296 tftp_process_read(pcb, ip, port, fname); 297 break; 298 case TFTP_WRQ: 299 //从payload中获取文件名 300 strcpy(fname, p-payload FIL_NAME_OFFSET); 301 printf(TFTP WRQ (write request): %s\r\n, fname); 302 tftp_process_write(pcb, ip, port, fname); 303 break; 304 default: 305 //发送访问冲突消息 306 tftp_send_error_packet(pcb, ip, port, TFTP_ERR_ILLEGALOP); 307 printf(TFTP unknown request op: %d\r\n\r\n, op); 308 udp_remove(pcb); 309 break; 310 } 311 312 cleanup: 313 pbuf_free(p); 314 }当TFTP客户端发起写入或读取文件的请求后lwip协议栈调用回调函数tftp_server_recv_cb。该回调函数通过tftp_get_opcode宏获取客户端发送报文的操作码不同的操作码执行该函数switch分支中的不同的case如对于写入文件请求则执行“case TFTP_WRQ”分支语句该分支语句调用TFTP处理写文件请求函数tftp_process_write该函数实现如下 233 //TFTP 处理写文件请求 234 static int tftp_process_write(struct udp_pcb *pcb, ip_addr_t *ip, int port, 235 char *fname) 236 { 237 tftp_connection_args *conn; 238 FIL w_fil; 239 FRESULT Res; 240 241 Res f_open(w_fil, fname, FA_CREATE_ALWAYS | FA_WRITE); 242 if (Res) { 243 xil_printf(Unable to open file %s for writing %d\r\n, fname, 244 Res); 245 tftp_send_error_packet(pcb, ip, port, TFTP_ERR_DISKFULL); 246 udp_remove(pcb); 247 return -1; 248 } 249 250 conn mem_malloc(sizeof *conn); 251 if (!conn) { 252 xil_printf(Unable to allocate memory for tftp conn\r\n); 253 tftp_send_error_packet(pcb, ip, port, TFTP_ERR_DISKFULL); 254 udp_remove(pcb); 255 return -1; 256 } 257 258 memcpy(conn-fil, w_fil, sizeof(w_fil)); 259 conn-block 0; 260 261 //为该pcb设置接收回调 262 udp_recv(pcb, (udp_recv_fn) tftp_server_write_req_recv_cb, conn); 263 264 //通过发送第一个ACK来启动传输 265 tftp_send_ack_packet(pcb, ip, port, conn-block); 266 267 return 0; 268 }该函数首先在文件系统中创建一个文件文件名为客户端写入的文件名然后为新创建的UDP PCB设置接收回调函数用于处理后面接收客户端传入的文件最后发送块编号为0的ACK报文以应答客户端启动传输。TFTP写入请求的接收回调函数实现如下 187 //TFTP 写入请求的接收回调函数 188 static void tftp_server_write_req_recv_cb(void *_args, struct udp_pcb *upcb, 189 struct pbuf *p, ip_addr_t *addr, u16_t port) 190 { 191 ip_addr_t ip *addr; 192 tftp_connection_args *args (tftp_connection_args *)_args; 193 194 if (p-len ! p-tot_len) { 195 xil_printf(TFTP_WRQ: Tftp server does not support 196 chained pbufs\r\n); 197 pbuf_free(p); 198 return; 199 } 200 201 //确保数据块是我们所期望的 202 if ((p-len TFTP_PACKET_HDR_LEN) 203 (tftp_get_block_value(p-payload) 204 (u16_t) (args-block 1))) { 205 206 //将接收的数据写入文件 207 unsigned int n; 208 f_write(args-fil, p-payload TFTP_PACKET_HDR_LEN, 209 p-len - TFTP_PACKET_HDR_LEN, n); 210 if (n ! p-len - TFTP_PACKET_HDR_LEN) { 211 xil_printf(TFTP_WRQ: Write to file error\r\n); 212 tftp_send_error_packet(upcb, ip, port, 213 TFTP_ERR_DISKFULL); 214 pbuf_free(p); 215 return tftp_cleanup(upcb, args); 216 } 217 args-block; 218 } 219 220 tftp_send_ack_packet(upcb, ip, port, args-block); 221 222 223 224 //如果接收到的数据段长度小于指定的字节数则表明已经接收了整个文件因此可以退出 225 if (p-len TFTP_DATA_PACKET_MSG_LEN) { 226 xil_printf(TFTP_WRQ: Transfer completed\r\n\r\n); 227 return tftp_cleanup(upcb, args); 228 } 229 230 pbuf_free(p); 231 }从该回调函数可以看到TFTP服务端对客户端发送的数据报文的块编号进行校验如果不是我们期望的块编号就重发上一次发送的ACK报文如果是期望的块编号就将数据写入文件中然后递增块编号并发送ACK报文给客户端以确认收到数据。 在该函数的最后判断接收到的数据段长度是否小于指定的字节数TFTP_DATA_PACKET_MSG_LEN如果是则表明已经接收了整个文件因此可以结束连接。TFTP_DATA_PACKET_MSG_LEN在lwip_tftp_server.h宏定义为512。 以上大概的讲解了TFTP Server接收客户端写入文件的实现。下面我们进行实际操作看看TFTP客户端是否能向服务器写入文件。 33.5下载验证 首先我们将下载器与MPSOC开发板上的JTAG接口连接下载器另外一端与电脑连接。然后使用USB连接线将USB UART接口与电脑连接用于串口通信。使用网线一端连接MPSOC开发板的以太网接口另一端与电脑或路由器连接。连接完成后在开发板上插入TF 卡SD 卡插槽位于开发板背面。最后连接开发板的电源给开发板上电。如下图所示 图 34.5.1 MPSOC开发板实物图 现在进入最后一步。 step6板级验证 6-1 在Vitis软件的下方的Vitis Serial Terminal窗口中点击右上角的加号连接串口。 6-2 下载程序。下载完成后可以看到串口打印的结果如下 图 34.5.2 显示打印结果 其中“File system initialization successful”表明SD卡可以正常工作。打印的最后一句表明了该实验如何使用。由于是TFTP服务器实验所以我们需要TFTP客户端可以从网上下载也可以使用Windows系统的CMD命令行界面如果开启了TFTP客户端开启方法见步骤6-5。 6-3 下面我们先创建一个文件用来传输到TFTP服务器。文件存放位置任意文件内容任意。 我们在Vivado工程目录新建一个名为“test”的文件夹里面新建一个名为testfile.txt的文件文件内容为“这只是一个测试文件。”如下图所示 图 34.5.3 新建一个名为test_file.txt的文件 6-4 我们打开电脑的CMD按winr键后输入cmd然后输入命令“cd /D F:\ZYNQ\Embedded_System\lwip_tftp_server\test”切换到 “F:\ZYNQ\Embedded_System\lwip_tftp_server\test”目录下如下图所示 图 34.5.4 切换到上传文件所在的目录 然后输入“tftp -i 192.168.1.10 PUT testfile.txt”命令回车会显示传输成功字样如下图所示 图 34.5.5 进行tftp连接 此时VITIS串口终端也会打印如下信息 图 34.5.6 串口终端打印写入完成信息 如果回车后出现像下图所示界面所示“tftp不是内部或外部命令也不是可运行的程序或批处理文件”则表明未开启Windows的tftp客户端功能开启方式见6-5。 图 34.5.7 未启用tftp客户端时的界面 如果回车后出现连接请求失败或者串口终端打印“Error creating PCB.Out of Memory”信息时检查防火墙是否全部关闭。 向服务器写入文件刚才测试完成了现在测试从服务器端读取文件可以读取刚才写入的文件也可以读取服务器程序创建的测试文件。下面我们以读取服务器程序创建的测试文件为例进行读取文件测试。 在CMD中输入“tftp -i 192.168.1.10 GET sample1.txt”命令然后回车会显示传输成功字样如下图所示 图 34.5.8 输入读取文件命令 此时VITIS串口终端也会打印如下信息 图 34.5.9 读取成功 此时我们打开test文件夹会看到其中新增了sample1.txt双击打开其内容如下 图 34.5.10 读取的sample1.txt文件 可以看到读取文件测试成功。现在我们把SD卡插到电脑上查看其内容如下 图 34.5.11 SD卡上的文件 可以看到客户端上传给TFTP服务器的文件确实写到SD卡中。 6-5 下面我们介绍一下如何开启Windows的tftp客户端功能。在Win10或Win7系统中按“Winr”快捷键后在下图所示界面中输入“control”。 图 34.5.12 打开控制面板界面 进入下图所示控制面板界面将查看方式设置为“类别”单击“程序”下的“卸载程序”如下图所示 图 34.5.13 点击进入“程序和功能”界面 在弹出的界面中单击“启用或关闭Windows功能”如下图所示 图 34.5.14 点击“启用或关闭Windows功能” 在弹出的“Windows功能”界面中找到“Tftp Client”并勾选如下图所示 图 34.5.15 勾选tftp client 单击确定后如果出现“Windows需要重启电脑才能完成安装所请求的更改”字样重新启动电脑即可。现在 Windows的tftp客户端服务已启用。 至此本实验完成。
http://www.dnsts.com.cn/news/93817.html

相关文章:

  • 做标准件网站多少企业需要网站建设
  • 四川省城乡住房建设部网站首页网站运营
  • 济南做微网站推广免费模板网页下载
  • 网站模板打包下载做一元购物网站
  • 泉州网站seo商务网站页面
  • 网站设计公司排行榜邯郸手机网站建设报价
  • 广州网站建设哪家便宜长春火车站什么时候解封
  • 网站ico制作百度关键词挖掘
  • 深圳优化网站关键词好网站推荐一下
  • 企业网站的页面特点新手建站论坛
  • 论坛式网站建设自动化的网站建设
  • 为什么小城市做不出来好的网站电商网站开发设计方法
  • 南昌网站建设公司市场外贸网站怎么做促销
  • 怎么挖掘网站的关键词沈阳app定制
  • 上海建设银行网站上班时间表wordpress主题汉化
  • 东莞企慕网站建设网站制作河南
  • 做网站运营有前途wordpress 链接 插件
  • 建设阿里巴巴网站WordPress 上传头像 前端
  • 北京房产网站大全seo内链优化
  • 学校网站建设管理制度关于建设门户网站的通知
  • 上海市场监督管理局网站深圳软件系统开发公司
  • 重庆专业建网站临平建设局网站
  • 网站到期可以续费网站后台上传word
  • 网站备案是什么意思网站建设推广重要性
  • 用老域名做新网站 权重怎么传递济南专业网站建设咨询
  • 厦门 外贸网站网站开发与维护说明
  • 免费营销网站制作模板wordpress 文字弹窗
  • 网站不备案会怎...wordpress 调用导航栏
  • 自己做的网站能备案创建众筹网站
  • 做电子相册的大网站公司网站模板图片