当前位置:   article > 正文

tcp/ip(二)_用s l i p链接运行一个交互式应用程序,同时还运行另一个应用程序如 f t p发送或接

用s l i p链接运行一个交互式应用程序,同时还运行另一个应用程序如 f t p发送或接

2.1 引言
从图1 - 4中可以看出,在T C P / I P协议族中,链路层主要有三个目的:(1)为I P模块发送和
接收I P数据报;( 2)为A R P模块发送A R P请求和接收A R P应答;(3)为R A R P发送R A R P请
求和接收R A R P应答。T C P / I P支持多种不同的链路层协议,这取决于网络所使用的硬件,如以
太网、令牌环网、F D D I(光纤分布式数据接口)及R S-2 3 2串行线路等。
在本章中,我们将详细讨论以太网链路层协议,两个串行接口链路层协议( S L I P和P P P),
以及大多数实现都包含的环回( l o o p b a c k)驱动程序。以太网和S L I P是本书中大多数例子使
用的链路层。对M T U(最大传输单元)进行了介绍,这个概念在本书的后面章节中将多次遇
到。我们还讨论了如何为串行线路选择M T U。
2.2 以太网和IEEE 802封装
以太网这个术语一般是指数字设备公司( Digital Equipment Corp.)、英特尔公司( I n t e l
C o r p .)和X e r o x公司在1 9 8 2年联合公布的一个标准。它是当今T C P / I P采用的主要的局域网技
术。它采用一种称作C S M A / C D的媒体接入方法,其意思是带冲突检测的载波侦听多路接入
(Carrier Sense, Multiple Access with Collision Detection)。它的速率为10 Mb/s,地址为48 bit。
几年后, I E E E(电子电气工程师协会) 8 0 2委员会公布了一个稍有不同的标准集,其中
8 0 2 . 3针对整个C S M A / C D网络,8 0 2 . 4针对令牌总线网络, 8 0 2 . 5针对令牌环网络。这三者的共
同特性由8 0 2 . 2标准来定义,那就是8 0 2网络共有的逻辑链路控制( L L C)。不幸的是,8 0 2 . 2和
8 0 2 . 3定义了一个与以太网不同的帧格式。文献[Stallings 1987]对所有的IEEE 802标准进行了
详细的介绍。
在T C P / I P世界中,以太网I P数据报的封装是在RFC 894[Hornig 1984]中定义的,IEEE 802
网络的I P数据报封装是在RFC 1042[Postel and Reynolds 1988]中定义的。主机需求R F C要求每
台I n t e r n e t主机都与一个10 Mb/s的以太网电缆相连接:
1) 必须能发送和接收采用RFC 894(以太网)封装格式的分组。
2) 应该能接收与RFC 894混合的RFC 1042(IEEE 802)封装格式的分组。
3) 也许能够发送采用RFC 1042格式封装的分组。如果主机能同时发送两种类型的分组数
据,那么发送的分组必须是可以设置的,而且默认条件下必须是RFC 894分组。
最常使用的封装格式是RFC 894定义的格式。图2 - 1显示了两种不同形式的封装格式。图
中每个方框下面的数字是它们的字节长度。
两种帧格式都采用48 bit(6字节)的目的地址和源地址( 8 0 2 . 3允许使用16 bit的地址,但
一般是48 bit地址)。这就是我们在本书中所称的硬件地址。A R P和R A R P协议(第4章和第5章)
对32 bit的I P地址和48 bit的硬件地址进行映射。
接下来的2个字节在两种帧格式中互不相同。在8 0 2标准定义的帧格式中,长度字段是指
该书下载自-书部落-分享计算机经典巨著!--www.shubulo.com!仅供试看^_^
它后续数据的字节长度,但不包括C R C检验码。以太网的类型字段定义了后续数据的类型。
在8 0 2标准定义的帧格式中,类型字段则由后续的子网接入协议( Sub-network Access
P r o t o c o l,S N A P)的首部给出。幸运的是, 8 0 2定义的有效长度值与以太网的有效类型值无一
相同,这样,就可以对两种帧格式进行区分。
在以太网帧格式中,类型字段之后就是数据;而在8 0 2帧格式中,跟随在后面的是3字节
的802.2 LLC和5字节的802.2 SNAP。目的服务访问点( Destination Service Access Point,
D S A P)和源服务访问点( Source Service Access Point, SSAP)的值都设为0 x a a。Ct r l字段的
值设为3。随后的3个字节o rg code都置为0。再接下来的2个字节类型字段和以太网帧格式一样
(其他类型字段值可以参见RFC 1340 [Reynolds and Postel 1992])。
C R C字段用于帧内后续字节差错的循环冗余码检验(检验和)(它也被称为F C S或帧检验
序列)。
8 0 2 . 3标准定义的帧和以太网的帧都有最小长度要求。8 0 2 . 3规定数据部分必须至少为3 8字
节,而对于以太网,则要求最少要有4 6字节。为了保证这一点,必须在不足的空间插入填充
(p a d)字节。在开始观察线路上的分组时将遇到这种最小长度的情况。
在本书中,我们在需要的时候将给出以太网的封装格式,因为这是最为常见的封装格式。
16使用TCP/IP详解,卷1:协议
下载
目的地址源地址长度类型数据
数据报
38~1492
46~1500
46~1500
38~1492
请求/应答
请求/应答
46~1500字节
数据
数据报
请求/应答
请求/应答
类型
0800
类型
0806
类型
8035
类型
0800
类型
0806
类型
8035
目的地址源地址类型
以太网封装
图2-1 IEEE 802.2/802.3(RFC 1042)和以太网的封装格式(RFC 894)
该书下载自-书部落-分享计算机经典巨著!--www.shubulo.com!仅供试看^_^
2.3 尾部封装
RFC 893[Leffler and Karels 1984]描述了另一种用于以太网的封装格式,称作尾部封装
(trailer encapsulation)。这是一个早期B S D系统在DEC VA X机上运行时的试验格式,它通过
调整I P数据报中字段的次序来提高性能。在以太网数据帧中,开始的那部分是变长的字段
(I P首部和T C P首部)。把它们移到尾部(在C R C之前),这样当把数据复制到内核时,就可以
把数据帧中的数据部分映射到一个硬件页面,节省内存到内存的复制过程。T C P数据报的长
度是5 1 2字节的整数倍,正好可以用内核中的页表来处理。两台主机通过协商使用A R P扩展协
议对数据帧进行尾部封装。这些数据帧需定义不同的以太网帧类型值。
现在,尾部封装已遭到反对,因此我们不对它举任何例子。有兴趣的读者请参阅RFC 893
以及文献[ L e ffler et al. 1989]的11 . 8节。
2.4 SLIP:串行线路IP
S L I P的全称是Serial Line IP。它是一种在串行线路上对I P数据报进行封装的简单形式,在
RFC 1055[Romkey 1988]中有详细描述。S L I P适用于家庭中每台计算机几乎都有的R S - 2 3 2串
行端口和高速调制解调器接入I n t e r n e t。
下面的规则描述了S L I P协议定义的帧格式:
1) IP数据报以一个称作E N D(0 x c 0)的特殊字符结束。同时,为了防止数据报到来之前
的线路噪声被当成数据报内容,大多数实现在数据报的开始处也传一个E N D字符(如果有线
路噪声,那么E N D字符将结束这份错误的报文。这样当前的报文得以正确地传输,而前一个
错误报文交给上层后,会发现其内容毫无意义而被丢弃)。
2) 如果I P报文中某个字符为E N D,那么就要连续传输两个字节0 x d b和0 x d c来取代它。
0 x d b这个特殊字符被称作S L I P的E S C字符,但是它的值与A S C I I码的E S C字符(0 x 1 b)不同。
3) 如果I P报文中某个字符为S L I P的E S C字符,那么就要连续传输两个字节0 x d b和0 x d d来
取代它。
图2 - 2中的例子就是含有一个E N D字符和一个E S C字符的I P报文。在这个例子中,在串行
线路上传输的总字节数是原I P报文长度再加4个字节。
图2-2 SLIP报文的封装
S L I P是一种简单的帧封装方法,还有一些值得一提的缺陷:
1) 每一端必须知道对方的I P地址。没有办法把本端的I P地址通知给另一端。
2) 数据帧中没有类型字段(类似于以太网中的类型字段)。如果一条串行线路用于S L I P,
那么它不能同时使用其他协议。
第2章链路层使用17
下载
IP数据报
该书下载自-书部落-分享计算机经典巨著!--www.shubulo.com!仅供试看^_^
3 ) S L I P没有在数据帧中加上检验和(类似于以太网中的C R C字段)。如果S L I P传输的报
文被线路噪声影响而发生错误,只能通过上层协议来发现(另一种方法是,新型的调制解调
器可以检测并纠正错误报文)。这样,上层协议提供某种形式的C R C就显得很重要。在第3章
和第1 7章中,我们将看到I P首部和T C P首部及其数据始终都有检验和。在第11章中,将看到
U D P首部及其数据的检验和却是可选的。
尽管存在这些缺点, S L I P仍然是一种广泛使用的协议。
S L I P的历史要追溯到1 9 8 4年,Rick Adams第一次在4 . 2 B S D系统中实现。尽管它本
身的描述是一种非标准的协议,但是随着调制解调器的速率和可靠性的提高, S L I P越
来越流行。现在,它的许多产品可以公开获得,而且很多厂家都支持这种协议。
2.5 压缩的SLIP
由于串行线路的速率通常较低( 19200 b/s或更低),而且通信经常是交互式的(如Te l n e t
和R l o g i n,二者都使用T C P),因此在S L I P线路上有许多小的T C P分组进行交换。为了传送1个
字节的数据需要2 0个字节的I P首部和2 0个字节的T C P首部,总数超过4 0个字节(1 9 . 2节描述了
R l o g i n会话过程中,当敲入一个简单命令时这些小报文传输的详细情况)。
既然承认这些性能上的缺陷,于是人们提出一个被称作C S L I P(即压缩S L I P)的新协议,
它在RFC 1144[Jacobson 1990a]中被详细描述。C S L I P一般能把上面的4 0个字节压缩到3或5个
字节。它能在C S L I P的每一端维持多达1 6个T C P连接,并且知道其中每个连接的首部中的某些
字段一般不会发生变化。对于那些发生变化的字段,大多数只是一些小的数字和的改变。这
些被压缩的首部大大地缩短了交互响应时间。
现在大多数的S L I P产品都支持C S L I P。作者所在的子网(参见封面内页)中有两条
SLIP链路,它们均是CSLIP链路。
2.6 PPP:点对点协议
P P P,点对点协议修改了S L I P协议中的所有缺陷。P P P包括以下三个部分:
1) 在串行链路上封装I P数据报的方法。P P P既支持数据为8位和无奇偶检验的异步模式
(如大多数计算机上都普遍存在的串行接口),还支持面向比特的同步链接。
2) 建立、配置及测试数据链路的链路控制协议( L C P:Link Control Protocol)。它允许通
信双方进行协商,以确定不同的选项。
3) 针对不同网络层协议的网络控制协议( N C P:Network Control Protocol)体系。当前
R F C定义的网络层有I P、O S I网络层、D E C n e t以及A p p l e Ta l k。例如,IP NCP允许双方商定是
否对报文首部进行压缩,类似于C S L I P(缩写词N C P也可用在T C P的前面)。
RFC 1548[Simpson 1993]描述了报文封装的方法和链路控制协议。RFC 1332[McGregor
1 9 9 2 ]描述了针对I P的网络控制协议。
P P P数据帧的格式看上去很像I S O的H D L C(高层数据链路控制)标准。图2 - 3是P P P数据
帧的格式。
每一帧都以标志字符0 x 7 e开始和结束。紧接着是一个地址字节,值始终是0 x ff,然后是一
个值为0 x 0 3的控制字节。
18使用TCP/IP详解,卷1:协议
下载
该书下载自-书部落-分享计算机经典巨著!--www.shubulo.com!仅供试看^_^
图2-3 PPP数据帧的格式
接下来是协议字段,类似于以太网中类型字段的功能。当它的值为0 x 0 0 2 1时,表示信息
字段是一个I P数据报;值为0 x c 0 2 1时,表示信息字段是链路控制数据;值为0 x 8 0 2 1时,表示
信息字段是网络控制数据。
C R C字段(或F C S,帧检验序列)是一个循环冗余检验码,以检测数据帧中的错误。
由于标志字符的值是0 x 7 e,因此当该字符出现在信息字段中时, P P P需要对它进行转义。
在同步链路中,该过程是通过一种称作比特填充(bit stuff i n g )的硬件技术来完成的[ Ta n e n b a u m
1 9 8 9 ]。在异步链路中,特殊字符0 x 7 d用作转义字符。当它出现在P P P数据帧中时,那么紧接
着的字符的第6个比特要取其补码,具体实现过程如下:
1) 当遇到字符0 x 7 e时,需连续传送两个字符: 0 x 7 d和0 x 5 e,以实现标志字符的转义。
2) 当遇到转义字符0 x 7 d时,需连续传送两个字符: 0 x 7 d和0 x 5 d,以实现转义字符的转义。
3 ) 默认情况下,如果字符的值小于0 x 2 0(比如,一个A S C I I控制字符),一般都要进行转
义。例如,遇到字符0 x 0 1时需连续传送0 x 7 d和0 x 2 1两个字符(这时,第6个比特取补码后变为
1,而前面两种情况均把它变为0)。
这样做的原因是防止它们出现在双方主机的串行接口驱动程序或调制解调器中,因为有
时它们会把这些控制字符解释成特殊的含义。另一种可能是用链路控制协议来指定是否需要
对这3 2个字符中的某一些值进行转义。默认情况下是对所有的3 2个字符都进行转义。
与S L I P类似,由于P P P经常用于低速的串行链路,因此减少每一帧的字节数可以降低应用
程序的交互时延。利用链路控制协议,大多数的产品通过协商可以省略标志符和地址字段,
并且把协议字段由2个字节减少到1个字节。如果我们把P P P的帧格式与前面的S L I P的帧格式
(图2 - 2)进行比较会发现, P P P只增加了3个额外的字节: 1个字节留给协议字段,另2个给
C R C字段使用。另外,使用I P网络控制协议,大多数的产品可以通过协商采用Van Jacobson报
文首部压缩方法(对应于C S L I P压缩),减小I P和T C P首部长度。
总的来说, P P P比S L I P具有下面这些优点: (1) PPP支持在单根串行线路上运行多种协议,
不只是I P协议;(2) 每一帧都有循环冗余检验; (3) 通信双方可以进行I P地址的动态协商(使用
I P网络控制协议); (4) 与C S L I P类似,对T C P和I P报文首部进行压缩; (5) 链路控制协议可以
对多个数据链路选项进行设置。为这些优点付出的代价是在每一帧的首部增加3个字节,当建
立链路时要发送几帧协商数据,以及更为复杂的实现。
尽管P P P比S L I P有更多的优点,但是现在的S L I P用户仍然比P P P用户多。随着产品
越来越多,产家也开始逐渐支持PPP,因此最终PPP应该取代SLIP。
第2章链路层使用19
下载
标志地址控制协议
协议
协议
协议
网络控制数据
链路控制数据
IP数据报
最多1500字节
信息标志
该书下载自-书部落-分享计算机经典巨著!--www.shubulo.com!仅供试看^_^
2.7 环回接口
大多数的产品都支持环回接口( Loopback Interface),以允许运行在同一台主机上的客户
程序和服务器程序通过T C P / I P进行通信。A类网络号1 2 7就是为环回接口预留的。根据惯例,
大多数系统把I P地址1 2 7 . 0 . 0 . 1分配给这个接口,并命名为l o c a l h o s t。一个传给环回接口的I P数
据报不能在任何网络上出现。
我们想象,一旦传输层检测到目的端地址是环回地址时,应该可以省略部分传输层和所
有网络层的逻辑操作。但是大多数的产品还是照样完成传输层和网络层的所有过程,只是当
I P数据报离开网络层时把它返回给自己。
图2 - 4是环回接口处理I P数据报的简单过程。
图2-4 环回接口处理IP数据报的过程
图中需要指出的关键点是:
1) 传给环回地址(一般是1 2 7 . 0 . 0 . 1)的任何数据均作为I P输入。
2) 传给广播地址或多播地址的数据报复制一份传给环回接口,然后送到以太网上。这是
因为广播传送和多播传送的定义(第1 2章)包含主机本身。
3 ) 任何传给该主机I P地址的数据均送到环回接口。
看上去用传输层和I P层的方法来处理环回数据似乎效率不高,但它简化了设计,因为环
回接口可以被看作是网络层下面的另一个链路层。网络层把一份数据报传送给环回接口,就
像传给其他链路层一样,只不过环回接口把它返回到I P的输入队列中。
在图2 - 4中,另一个隐含的意思是送给主机本身I P地址的I P数据报一般不出现在相应的网
络上。例如,在一个以太网上,分组一般不被传出去然后读回来。某些B S D以太网的设备驱
动程序的注释说明,许多以太网接口卡不能读回它们自己发送出去的数据。由于一台主机必
20使用TCP/IP详解,卷1:协议
下载
IP输出
函数
IP输入
函数
放入IP输入
队列中
放入IP输入
队列中


是目的IP地址是否与接
口IP地址相同?
否,用ARP获
取目的主机的
以太网地址
环回驱动程序
目的I P地址是否与广播
地址或多播地址相同?
发送
以太网
接收
以太网驱
动程序
基于以太网帧
类型进行分用
该书下载自-书部落-分享计算机经典巨著!--www.shubulo.com!仅供试看^_^
须处理发送给自己的I P数据报,因此图2 - 4所示的过程是最为简单的处理办法。
4 . 4 B S D系统定义了变量u s e l o o p b a c k,并初始化为1。但是,如果这个变量置为0,
以太网驱动程序就会把本地分组送到网络,而不是送到环回接口上。它也许不能工作,
这取决于所使用的以太网接口卡和设备驱动程序。
2.8 最大传输单元MTU
正如在图2 - 1看到的那样,以太网和8 0 2 . 3对数据帧的长度都有一个限制,其最大值分别是
1 5 0 0和1 4 9 2字节。链路层的这个特性称作
M T U,最大传输单元。不同类型的网络大
多数都有一个上限。
如果I P层有一个数据报要传,而且数
据的长度比链路层的M T U还大,那么I P层
就需要进行分片( f r a g m e n t a t i o n),把数据
报分成若干片,这样每一片都小于M T U。
我们将在11 . 5节讨论I P分片的过程。
图2 - 5列出了一些典型的M T U值,它们
摘自RFC 1191[Mogul and Deering 1990]。点到点的链路层(如S L I P和P P P)的M T U并非指的
是网络媒体的物理特性。相反,它是一个逻辑限制,目的是为交互使用提供足够快的响应时
间。在2 . 1 0节中,我们将看到这个限制值是如何计算出来的。
在3 . 9节中,我们将用n e t s t a t命令打印出网络接口的M T U。
2.9 路径MTU
当在同一个网络上的两台主机互相进行通信时,该网络的M T U是非常重要的。但是如果
两台主机之间的通信要通过多个网络,那么每个网络的链路层就可能有不同的M T U。重要的
不是两台主机所在网络的M T U的值,重要的是两台通信主机路径中的最小M T U。它被称作路
径M T U。
两台主机之间的路径M T U不一定是个常数。它取决于当时所选择的路由。而选路不一定
是对称的(从A到B的路由可能与从B到A的路由不同),因此路径M T U在两个方向上不一定是
一致的。
RFC 1191[Mogul and Deering 1990]描述了路径M T U的发现机制,即在任何时候确定路径
M T U的方法。我们在介绍了I C M P和I P分片方法以后再来看它是如何操作的。在11 . 6节中,我
们将看到I C M P的不可到达错误就采用这种发现方法。在11 . 7节中,还会看到, t r a c e r o u t e程序
也是用这个方法来确定到达目的节点的路径M T U。在11 . 8节和2 4 . 2节,将介绍当产品支持路
径M T U的发现方法时,U D P和T C P是如何进行操作的。
2.10 串行线路吞吐量计算
如果线路速率是9600 b/s,而一个字节有8 bit,加上一个起始比特和一个停止比特,那么
线路的速率就是960 B/s(字节/秒)。以这个速率传输一个1 0 2 4字节的分组需要1066 ms。如果
第2章链路层使用21
下载
图2-5 几种常见的最大传输单元(MTU)
超通道
以太网
网络MTU字节
点对点(低时延)
s令牌环(IBM)
s令牌环(IEEE 802.5)
该书下载自-书部落-分享计算机经典巨著!--www.shubulo.com!仅供试看^_^
用S L I P链接运行一个交互式应用程序,同时还运行另一个应用程序如F T P发送或接收1 0 2 4字
节的数据,那么一般来说就必须等待一半的时间( 533 ms)才能把交互式应用程序的分组数
据发送出去。
假定交互分组数据可以在其他“大块”分组数据发送之前被发送出去。大多数的S L I P实
现确实提供这类服务排队方法,把交互数据放在大块的数据前面。交互通信一般有Te l n e t、
R l o g i n以及F T P的控制部分(用户的命令,而不是数据)。
这种服务排队方法是不完善的。它不能影响已经进入下游(如串行驱动程序)队
列的非交互数据。同时,新型的调制解调器具有很大的缓冲区,因此非交互数据可能
已经进入该缓冲区了。
对于交互应用来说,等待533 ms是不能接受的。关于人的有关研究表明,交互响应时间
超过1 0 0~200 ms就被认为是不好的[Jacobson 1990a]。这是发送一份交互报文出去后,直到
接收到响应信息(通常是出现一个回显字符)为止的往返时间。
把S L I P的M T U缩短到2 5 6就意味着链路传输一帧最长需要266 ms ,它的一半是133 ms
(这是一般需要等待的时间)。这样情况会好一些,但仍然不完美。我们选择它的原因(与6 4
或1 2 8相比)是因为大块数据提供良好的线路利用率(如大文件传输)。假设C S L I P的报文首
部是5个字节,数据帧总长为2 6 1个字节,2 5 6个字节的数据使线路的利用率为9 8 . 1 %,帧头占
了1 . 9 %,这样的利用率是很不错的。如果把M T U降到2 5 6以下,那么将降低传输大块数据的
最大吞吐量。
在图2 - 5列出的M T U值中,点对点链路的M T U是2 9 6个字节。假设数据为2 5 6字节,T C P和
I P首部占4 0个字节。由于M T U是I P向链路层查询的结果,因此该值必须包括通常的T C P和I P
首部。这样就会导致I P如何进行分片的决策。I P对于C S L I P的压缩情况一无所知。
我们对平均等待时间的计算(传输最大数据帧所需时间的一半)只适用于S L I P链路(或
P P P链路)在交互通信和大块数据传输这两种情况下。当只有交互通信时,如果线路速率是
9600 b/s,那么任何方向上的1字节数据(假设有5个字节的压缩帧头)往返一次都大约需要
12.5 ms。它比前面提到的100~200 ms要小得多。需要注意的是,由于帧头从4 0个字节压缩到
5个字节,使得1字节数据往返时间从85 ms 减到12.5 ms。
不幸的是,当使用新型的纠错和压缩调制解调器时,这样的计算就更难了。这些调制解
调器所采用的压缩方法使得在线路上传输的字节数大大减少,但纠错机制又会增加传输的时
间。不过,这些计算是我们进行合理决策的入口点。
在后面的章节中,我们将用这些串行线路吞吐量的计算来验证数据从串行线路上通过的
时间。
2.11 小结
本章讨论了I n t e r n e t协议族中的最底层协议,链路层协议。我们比较了以太网和I E E E
8 0 2 . 2 / 8 0 2 . 3的封装格式,以及S L I P和P P P的封装格式。由于S L I P和P P P经常用于低速的链路,
二者都提供了压缩不常变化的公共字段的方法。这使交互性能得到提高。
大多数的实现都提供环回接口。访问这个接口可以通过特殊的环回地址,一般为
1 2 7 . 0 . 0 . 1。也可以通过发送I P数据报给主机所拥有的任一I P地址。当环回数据回到上层的协议
栈中时,它已经过传输层和I P层完整的处理过程。
22使用TCP/IP详解,卷1:协议
下载
该书下载自-书部落-分享计算机经典巨著!--www.shubulo.com!仅供试看^_^
我们描述了很多链路都具有的一个重要特性, M T U,相关的一个概念是路径M T U。根据
典型的串行线路M T U,对S L I P和C S L I P链路的传输时延进行了计算。
本章的内容只覆盖了当今T C P / I P所采用的部分数据链路公共技术。T C P / I P成功的原因之
一是它几乎能在任何数据链路技术上运行。

习题
2.1 如果你的系统支持n e t s t a t( 1 )命令(参见3 . 9节),那么请用它确定系统上的接口及其
M T U。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/146951
推荐阅读
相关标签
  

闽ICP备14008679号