lec 1 网络编程基础.ppt

上传人:qwe****56 文档编号:70014052 上传时间:2023-01-14 格式:PPT 页数:65 大小:1.67MB
返回 下载 相关 举报
lec 1 网络编程基础.ppt_第1页
第1页 / 共65页
lec 1 网络编程基础.ppt_第2页
第2页 / 共65页
点击查看更多>>
资源描述

《lec 1 网络编程基础.ppt》由会员分享,可在线阅读,更多相关《lec 1 网络编程基础.ppt(65页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、网络安全编程技术2/65课程主要内容n网络编程基础n安全编码n网络安全应用编程n数据包的捕获n端口扫描n主机扫描n防火墙nCryptoAPI编程n基于网络协议的信息隐藏编程3/65参考教材n1.网络安全编程技术与实例,刘文涛,机械工业出版社,2008n2.计算机网络应用软件编程技术,吴英,机械工业出版社,2010n3.网络安全编程与实践,陈卓等,国防工业出版社,20084/65第一讲:网络编程基础主要内容:nTCP/IP协议基础nSocket编程基础 5/651.TCP/IP协议族分层应用层应用层应用层应用层各种应用程序:各种应用程序:各种应用程序:各种应用程序:TelnetTelnet、FT

2、PFTP、WWWWWW、SMTPSMTP负责处理特定的应用程序细节负责处理特定的应用程序细节负责处理特定的应用程序细节负责处理特定的应用程序细节运输层运输层运输层运输层(传输层)(传输层)(传输层)(传输层)网络层网络层网络层网络层(互联网层)(互联网层)(互联网层)(互联网层)链路层链路层链路层链路层(数据连路层(数据连路层(数据连路层(数据连路层/网网网网络接口层)络接口层)络接口层)络接口层)TCPTCP和和和和UDPUDP为两台主机上的应用程序提供为两台主机上的应用程序提供为两台主机上的应用程序提供为两台主机上的应用程序提供端到端的通信端到端的通信端到端的通信端到端的通信IPIP、IC

3、MPICMP和和和和IGMPIGMP处理分组在网络中的活动处理分组在网络中的活动处理分组在网络中的活动处理分组在网络中的活动操作系统中的设备驱动程序、操作系统中的设备驱动程序、操作系统中的设备驱动程序、操作系统中的设备驱动程序、计算机中对应的网络接口卡计算机中对应的网络接口卡计算机中对应的网络接口卡计算机中对应的网络接口卡 处理与电缆的物理接口细节处理与电缆的物理接口细节处理与电缆的物理接口细节处理与电缆的物理接口细节6/65TCP/IP协议族中不同层次的协议协议族中不同层次的协议用户进程用户进程用户进程用户进程用户进程用户进程用户进程用户进程TCPTCPUDPUDPICMPICMPIPIPI

4、GMPIGMPARPARP硬件接口硬件接口RARPRARP应用层应用层传输层传输层网络层网络层网络接口层网络接口层媒体媒体7/65数据进入协议栈时的封装过程数据进入协议栈时的封装过程 6 6 2 20 20 4目的地址源地址 类型CRC应用数据IP首部 TCP首部应用数据TCP首部用户数据Appl首部用户数据应用数据IP首部 TCP首部以太网帧以太网帧以太网帧以太网帧461500461500字节字节字节字节IPIP数据报数据报数据报数据报TCPTCP段段段段应用程序应用程序应用程序应用程序TCPTCPIPIP以太网以太网以太网以太网驱动程序驱动程序驱动程序驱动程序以太网以太网以太网以太网以太网

5、首部以太网首部以太网首部以太网首部以太网以太网以太网以太网尾部尾部尾部尾部8/65以太网数据帧的分用过程TelnetTelnetFTPFTPSMTPSMTPSNMPSNMPTFTPTFTPTCPTCPUDPUDPICMPICMPIPIPARPARP以太网驱以太网驱以太网驱以太网驱动程序动程序动程序动程序以太网硬件以太网硬件以太网硬件以太网硬件23232121252516116169696 617171 10800H0800H0806H0806HRARARPRP0835H0835H根据以太网头部中根据以太网头部中根据以太网头部中根据以太网头部中的帧类型进行分用的帧类型进行分用的帧类型进行分用的帧

6、类型进行分用根据根据根据根据IPIP头部中的头部中的头部中的头部中的协议值进行分用协议值进行分用协议值进行分用协议值进行分用根据根据根据根据TCPTCP或或或或UDPUDP头部中的端口头部中的端口头部中的端口头部中的端口号进行分用号进行分用号进行分用号进行分用9/65ApplicationTCP/UDPIPNetwork AccessApplicationTCP/UDPIPNetwork Access使用下层提供的服务提供上层一些服务10/65无连接通信n不同物理网络之间存在差异n通信能力、分组长度、延时n允许IP报文从不同路径达到目的地n路由器为每个IP报文独立选路nIP通信不保证可靠性,但

7、灵活性增加n多种网络都能满足的通信方式n允许多种选路策略(如可靠性、容量、延时)n结合应用考虑实际通信策略11/65运输层协议和网络层协议的主要区别 应用进程应用进程IP 协议的作用范围(提供主机之间的逻辑通信)TCP 和 UDP 协议的作用范围(提供进程之间的逻辑通信)因 特 网12/651.2 UDP概述 nUDP 只在 IP 的数据报服务之上增加了很少一点的功能,即端口的功能和可选的差错检测的功能。n虽然 UDP 用户数据报只能提供不可靠的交付,但 UDP 在某些方面有其特殊的优点。n发送数据之前不需要建立连接nUDP 的主机不需要维持复杂的连接状态表。nUDP 用户数据报只有8个字节的

8、首部开销。n网络出现的拥塞不会使源主机的发送速率降低。这对某些实时应用是很重要的。13/651.3 TCP概述n高层的许多应用需要n传输大量的数据n可靠的通信服务n无法容忍IP 或 UDP提供的无可靠性保证的服务n各种应用无法保证完全一致的可靠性方法nTCPn面向连接的n可靠的n字节流方式nFTP、SMTP、Telnet14/65同一系统中不同进程间进行通信时,通过系统分配的进程号(Process ID)就可以惟一标识一个进程。也就是说,要通信的进程只要知道对方的进程号就可以进行通信。而网络情况下进程间的通信问题就要复杂得多,不能只简单地用进程号来标识不同的进程,因为各主机都独立地分配其进程号

9、。为了惟一地标识网络中通信的一个进程(即通信的某一方),就要使用一个如下的三元组:(协议,本地IP地址,本地端口号)1.4 网络应用程序的标识问题15/65该怎样完整地表示网络中进行通信的两个进程,或一个通信流?(协议,本地地址,本地端口号,远地地址,远地端口号)网络应用程序的标识问题(续)16/652.1 Socket编程的提出 站在应用程序实现的角度,应用程序如何方便站在应用程序实现的角度,应用程序如何方便地使用协议栈软件进行通信呢?地使用协议栈软件进行通信呢?如果能在应用程序与协议栈软件之间提供一个如果能在应用程序与协议栈软件之间提供一个软件接口,就可以方便客户与服务器软件的编程。软件接

10、口,就可以方便客户与服务器软件的编程。套接字应用程序编程接口是网络应用程序通过套接字应用程序编程接口是网络应用程序通过网络协议栈进行通信时所使用的接口,即网络协议栈进行通信时所使用的接口,即应用程序应用程序与协议栈软件之间的接口与协议栈软件之间的接口,简称套接字编程接口,简称套接字编程接口(Socket API)。它定义了应用程序与协议栈软件进行交互时可它定义了应用程序与协议栈软件进行交互时可以使用的一组操作,决定了应用程序使用协议栈的以使用的一组操作,决定了应用程序使用协议栈的方式、应用程序所能实现的功能、以及开发具有这方式、应用程序所能实现的功能、以及开发具有这些功能的程序的难度。些功能的

11、程序的难度。17/65Socket编程的起源加州大学伯克利加州大学伯克利(Berkley)分校开发并推广了分校开发并推广了一个包括一个包括TCP/IP互联协议的互联协议的UNIX,称为称为BSD UNIX(Berkeley Software Distribution UNIX)操作系统,套接字编程接口操作系统,套接字编程接口是是这个操作这个操作系统的一个部分。系统的一个部分。后来的许多操作系统并没有另外搞一套其它后来的许多操作系统并没有另外搞一套其它的编程接口,而是选择了对于套接字编程接口的的编程接口,而是选择了对于套接字编程接口的支持。支持。由于这个套接字规范最早是由由于这个套接字规范最早是

12、由Berkeley大学大学开发的,一般将它称为开发的,一般将它称为Berkeley Sockets规范。规范。18/65Winsock规范的核心内容是符合Berkeley Socket风格的库函数,但为了使程序员能充分利用Windows消息驱动机制进行编程,又定义开发了一组针对Windows的扩展库函数(本门本门课程基本忽略该扩展课程基本忽略该扩展)。Windows Sockets规范中针对Windows的扩展 部 分,为 应 用 程 序 开 发 者 提 供 了 开 发Windows应用软件的功能,它有利于程序员写出更加高效的程序。另外,除了WSAStartup()和WSACleanup()两

13、个函数外,其他Windows扩展函数的使用不是强制性的。Windows Sockets19/652.2 什么是套接字(SOCKET)套接口是对网络中不同主机上应用进程之间进行套接口是对网络中不同主机上应用进程之间进行双向通信的端点的抽象,一个套接口就是网络上进双向通信的端点的抽象,一个套接口就是网络上进程通信的一端,提供了应用层进程利用网络协议栈程通信的一端,提供了应用层进程利用网络协议栈交换数据的机制交换数据的机制。电插座与电话插座的作用20/65 应用进程、套接口、网络协议栈及操作系统的关系应用进程、套接口、网络协议栈及操作系统的关系21/65 从从实实现现的的角角度度来来讲讲,非非常常复

14、复杂杂。套套接接字字是是一一个个复复杂杂的的软软件件机机构构,包包含含了了一一定定的的数数据据结结构构,包含许多选项,由操作系统内核管理。包含许多选项,由操作系统内核管理。从从使使用用的的角角度度来来讲讲,非非常常简简单单。对对于于套套接接字字的的操操作作形形成成了了一一种种网网络络应应用用程程序序的的编编程程接接口口(API)。)。把把这这一一套套操操作作套套接接字字的的编编程程接接口口函函数数称称作作套套接接字字编编程程接接口口,套套接接字字是是它它的的操操作作对对象象。总之,套接字是网络通信的基石。总之,套接字是网络通信的基石。什么是套接字(SOCKET)22/65为了满足不同的通信程序

15、对通信质量和性能的要求,一般的网络系统提供了三种不同类型的套接口,以供用户在设计网络应用程序时根据不同的要求来选择。这三种套接口分别是:(1)流式套接口(SOCK_STREAM)。(2)数据报套接口(SOCK_DGRAM)。(3)原始套接口(SOCK_RAW)。2.3 Socket的分类23/65 数据报套接字基于数据报套接字基于UDP协议协议24/65 流式套接字基于TCP协议25/65(3)原始式套接字(RAW SOCKET)n 原始式套接字允许对较低层次的协议,如IP、ICMP直接访问,可用于检验新的协议的实现,一般的程序员很少使用。26/652.4 使用确定的IP地址和传输层端口号往往

16、在生成套接字的描述符后,要将套接字与计算机上的特定的IP地址和传输层端口号相关联,这个过程称为绑定。一个套接口要使用一个确定的三元组网络地址信息,才能使它在网络中唯一地被标识。27/652.2.4 套接字使用的数据类型和相关的问题套接字使用的数据类型和相关的问题在在套套接接字字编编程程接接口口中中,专专门门定定义义了了三三种种结结构构型型的的数数据据类类型型,用用来来存存储储协协议议相相关关的的网网络络地地址址,在在套套接接字字编编程程接接口口的的函函数数调调用用中中要要用到它们。用到它们。三种表示套接字地址的结构28/65(1)Sockaddr 结构 sockaddr结构,针对各种通信域的套

17、接字,存储它们的地址信息。struct sockaddr unsigned short sa_family;/地址家族char sa_data14;/协议地址 29/65 专专门门针针对对Internet通通信信域域,存存储储套套接接字字相相关关的的网络地址信息,例如网络地址信息,例如IP地址,传输层端口号等信息。地址,传输层端口号等信息。struct sockaddr_in short int sin_family;/地址族地址族unsigned short sin_port;/端口号端口号struct in_addr sin_addr;/IP 地址地址unsigned char sin_z

18、ero8;/全为全为0struct sockaddr真的很一般吗?(2)sockaddr_in结构30/65 in_addr结构,专门用来存储结构,专门用来存储 IP地址。地址。Struct in_addr unsigned long s_addrl;(3)in_addr结构Socket 描述符描述符Socket(无符号整数无符号整数)32/652.5 Socket编程的一些基本函数n字节顺序转换函数nIp地址转换函数33/65 在具体计算机中的多字节数据的存储顺序,称为本机字节顺序。多字节数据在网络协议报头中的存储顺序,称为网络字节顺序。网络应用程序要在不同的计算机中运行,本机字节顺序是不同

19、的,但是,网络字节顺序是一定的。所以,应用程序在编程的时候,在把IP地址和端口号装入套接字的时候,应当把它们从本机字节顺序转换为网络字节顺序;相反,在本机输出时,应将它们从网络字节顺序转换为本机字节顺序。(1)本机字节顺序和网络字节顺序)本机字节顺序和网络字节顺序140.134.26.50Most Significant byte first(Network Byte Order)Least Significant byte first(大部分Host Byte Order)1401342650502613414034/65htons()短整数本机顺序转换为网络顺序,用于端口号。htonl()

20、长整数本机顺序转换为网络顺序,用于IP地址。ntohs()短整数网络顺序转换为本机顺序,用于端口号。ntohl()长整数网络顺序转化为本机顺序,用于IP地址。这四个函数将被转换的数值作为函数的参数,函数返回值是转换后的结果。字节顺序转换的四个函数字节顺序转换的四个函数35/65 在在因因特特网网中中,IP地地址址常常常常用用点点分分十十进进制制的的表表示示方方法法,但但在在套套接接字字中中,IP地地址址是是无无符符号号的的长长整整型型数数,套套接接字字编编程程接接口口设设置置了了两两个个函函数数,专专门门用用于于两种形式的两种形式的IP地址的转换。地址的转换。(2)点分十进制的)点分十进制的I

21、P地址的转换地址的转换unsigned long inet_addr(const char*cp)入口参数cp:点分十进制形式的IP地址 返回值:网络字节顺序的IP地址char*inet_ntoa(struct in_addr in)36/65(3)Winsock库的加载和停止n如果用户在没有正确加载Winsock DLL(ws2_32.dll)的情况下使用了其他的Winsock API函数,则被调用的函数返回WSANOTINITIALISED错误信息,代码为10093。n该函数在程序中的基本使用方法如下:n#includen/其他代码nWORD wVersionRequested;nWSAD

22、ATA wsaData;nwVersionRequested=MAKEWORD(2,2);nif(WSAStartup(wVersionRequested,&wasData)!=0)n n WSACleanup();nreturn;37/65(4)获取计算机名称int gethostname(char*name,int namelen);char HostName255;int Result;Result=gethostname(HostName,255);if(Result=SOCKET_ERROR)printf(gethostname failed with error%dn,WSAGet

23、LastError();return;38/65 可以将文字型的主机名直接转换成可以将文字型的主机名直接转换成IP地址,地址,struct hostent*gethostbyname(const char*name);入口参数:站点的主机名,域名,甚至可以是ip地址。返回值:是指向hostent 结构的指针,hostent结构主要包含主机名,返回地址的类型(一般是AF_INET),地址长度,主机网络地址列表等。函数函数getaddrinfo 的功能更强大,微软推荐使用,但也更复杂。(5)获取主机的网络地址39/65数据结构struct hostent struct hostent char F

24、AR*h_name;/*official name of host*/char FAR*FAR*h_aliases;/*alias list*/short h_addrtype;/*host address type*/short h_length;/*length of address*/char FAR*FAR*h_addr_list;/*list of addresses*/#define h_addr h_addr_list0 /*address,for backward compat*/;h_addr_list0h_addr_list1NULLh_addr_list40/65Geth

25、ostbyname的代码实例nP21的代码n有问题吗41/65Gethostbyname的实例(的实例(P72)Result=gethostname(HostName,255);if(Result=SOCKET_ERROR)printf(gethostname failed with error%dn,WSAGetLastError();return;Hostent=(struct hostent*)malloc(sizeof(struct hostent);Hostent=gethostbyname(HostName);for(int i=0;i+)if(Hostent-h_addr_lis

26、ti+Hostent-h_length=Hostent-h_name)/?printf(第%d个网络接口:n,i+1);printf(IP地址:%sn,inet_ntoa(*(IN_ADDR*)(Hostent-h_addr_listi);break;42/652.6 Socket的工作过程的工作过程43/65SOCKET Socket(int Protofamily,int Type,int Protocol);n返回值:返回值:INVALID_SOCKET(错误)请看 p24的代码SOCKET WSASocket(int Protofamily,int Type,int Protocol,

27、)(1)创建)创建Socket的的API44/65(2)绑定绑定Socket到指定地址的到指定地址的APInint Bind(SOCKET Sockfd,struct sockaddr*Addr,int Addrlen);返回值:返回值:0(正确),(正确),SOCKET_ERROR(错误)struct sockaddr_in ServerAddr;ServerSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);memset(&ServerAddr,0,sizeof(struct sockaddr_in);ServerAddr.sin_family=A

28、F_INET;ServerAddr.sin_port=htons(8080);ServerAddr.sin_addr.s_addr=htonl(INADDR_ANY);Result=bind(ServerSocket,(struct sockaddr*)&ServerAddr,sizeof(ServerAddr);if(Result!=0)/请看 p24的代码 45/65Bind函数中地址的几种设置方式函数中地址的几种设置方式46/65问题n可以绑定到任意的地址吗?nWSAEADDRNOTAVAIL n客户端代码中需要绑定吗?nBind函数的实质是什么?n给socket设置本地通信端(不仅仅是

29、本地通信端(不仅仅是IP地址喔)地址喔)47/65(3)监听监听APInint listen(SOCKET Sockfd,int Queuesize);nSockfd:已绑定的未连接的已绑定的未连接的Socket句柄句柄nQueuesize:监听队列的最大长度:监听队列的最大长度n返回值:返回值:0(正确),(正确),SOCKET_ERROR(错误)48/65int connect(SOCKET Sockfd,struct sockaddr*Service_addr,int Addrlen);Sockfd:未连接的未连接的Socket句柄句柄返回值:返回值:0(正确),(正确),SOCKET_

30、ERROR(错误)说明:如果Sockfd没有绑定,系统会先自动绑定没有绑定,系统会先自动绑定如果是如果是UDP,仅仅是建立默认的发送地址,仅仅是建立默认的发送地址(4)请求建立连接的)请求建立连接的API49/65SOCKET accept(SOCKET Sockfd,struct sockaddr*Addr,int*addrlen);Sockfd:处于监听状态的套接字:处于监听状态的套接字 Addr:可选,用于确定对方的地址:可选,用于确定对方的地址 addrlen:可选,用于确定对方的地址长度:可选,用于确定对方的地址长度 返回值:新建连接句柄(正确),返回值:新建连接句柄(正确),INV

31、ALID_SOCKET(错误)可选意味着什么?(5)接受连接的)接受连接的API50/65举例:举例:LISTEN(Sockfd,10);监听套接字使用缓冲区接纳多个客户端的连接请求监听套接字使用缓冲区接纳多个客户端的连接请求 51/65int send(SOCKET s,const char*buf,int len,int flags);flags标志一般不用若无错误发生,函数都返回所发送数据的字节数;在发生错误的情况下,函数返回SOCKET_ERROR错误,说明:send()适用于已已建建立立连连接接的的数据报或流式套接口发送数据。int sendto(SOCKET s,const cha

32、r*buf,int len,int flags,const struct sockaddr*to,int tolen);(6)发送数据的)发送数据的API52/65(7)接收数据的)接收数据的APInint recv(SOCKET sockfd,char*buf,int len,int flags);flags标志一般不用在无错误发生时,函数返回所接收的字节数,函数在连接结束时返回0;如果发生错误,则函数返回SOCKET_ERROR。如果连 接 被 强 制 中 止,那 么 recv将 以WSAECONNRESET错误失败返回。53/65(7)接收数据的)接收数据的API(续)(续)nrecv(

33、)适用于已建立连接的已建立连接的数据报或流式套接口。nrecv 函数的默认工作方式为阻塞,可通过设置函数的默认工作方式为阻塞,可通过设置Socket的选项来改变。的选项来改变。n如果接受区的缓存小于数据的大小会怎样?与传输如果接受区的缓存小于数据的大小会怎样?与传输层协议有关吗?层协议有关吗?nint recvfrom(SOCKET sockfd,char*buf,int len,int flags,struct sockaddr*from,int*fromlen);54/65(8)关闭)关闭Socket的的APInint closesocket(SOCKET sockfd);返回值:返回值:

34、0(正确),(正确),SOCKET_ERROR(错误)55/65基本的socket编程服务器代码(P31-P33)程序:tcpserver.c*目的:分配一个套接字,然后反复执行如下几步:*(1)等待客户的一个连接*(2)发送一个短消息给客户*(3)关闭与客户的连接*(4)转向(1)步*命令行语法:tcpserver(代码里固定端口)56/65Socket(面向连接),TCPsocket()connect()write()read()socket()bind()read()write()listen()accept()建立连接ClientServer57/65void main()char R

35、eceiveBuffer1024;if(Result=WSAStartup(MAKEWORD(2,2),&wsaData)!=0)printf(WSAStartup failed with error%dn,Result);return;ServerSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);if(ServerSocket 0)/?printf(socket failed with error%dn,WSAGetLastError();return;memset(&ServerAddr,0,sizeof(ServerAddr);ServerAd

36、dr.sin_family=AF_INET;ServerAddr.sin_port=htons(ServerPort);ServerAddr.sin_addr.s_addr =htonl(INADDR_ANY);Result=bind(ServerSocket,(SOCKADDR*)&ServerAddr,sizeof(ServerAddr);58/65if(Result 0)/?Result=listen(ServerSocket,5);/SOMAXCONN if(Result=SOCKET_ERROR)printf(listen failed with error%dn,WSAGetLas

37、tError();return;ClientAddrLen=sizeof(SOCKADDR);int SendLength;do NewSocket=accept(ServerSocket,(SOCKADDR*)&ClientAddr,&ClientAddrLen);if(NewSocket 0)/?return;59/65else do memset(ReceiveBuffer,0,sizeof(ReceiveBuffer);if(ReceiveLen=recv(NewSocket,ReceiveBuffer,1024,0)0)return;if(ReceiveLen=0)printf(Re

38、ceive Data Finishedn);else ReceiveBuffer1024=0;/?printf(“Receive Data:%sn”,ReceiveBuffer);SendLength=send(NewSocket,ReceiveBuffer,strlen(ReceiveBuffer),0);60/65if(SendLength 0)printf(send failed with error%dn,WSAGetLastError();return;else printf(Send Data:%sn,ReceiveBuffer);while(ReceiveLen!=0);if(c

39、losesocket(NewSocket)=SOCKET_ERROR);while(1);if(closesocket(ServerSocket)=SOCKET_ERROR)if(WSACleanup()=SOCKET_ERROR)61/65基本的socket编程客户端代码(P33-P35)n更简单n较类似n不同处n不需要处理多个请求n没有监听和连接,多了connect62/65基于UDP的socket C/S编程代码n与TCP的很类似n主要不同处:n没有listen,connectn接收和发送函数变了63/65Socket(无连接),UDPsocket()bind()sendto()recvfrom()sendto()ClientServersocket()bind()recvfrom()64/65上面代码的主要缺点n可能出现死锁n服务器不能支持并发请求n常见的解决方案1:多线程编程,对每个客户端的请求都建立一个新的线程来处理。HANDLE CreateThread()n常见的解决方案2:异步通信(事件通知),即select机制请感兴趣的同学 先自行学习。65/65作业n实现基于TCP或UDP的socket C/S编程代码,并进行编译和运行。n可选:实现多线程的socket C/S编程

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 技术资料 > 其他杂项

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁