梦见锡安
msgbartop
小舟从此逝,江海寄余生。
msgbarbottom

第十六章 网络IPC:套接字 | 2008年12月06日

1、概述

套接字的原始版本是BSD套接字[1],它是通信端点的抽象。可用于同一机器上的进程间通信,典型应用为Unix域套接字[2];也可用于通信网络上任何体系结构的计算机之间的通信,典型应用为互联网套接字[3]及在此基础上的TCP/IP协议栈[4]实现。

1983年,4.2 BSD发布了基于套接字技术的第一个TCP/IP协议栈API实现,它成为此后其它系统TCP/IP实现的基础。POSIX的socket(7)标准是在4.4 BSD的基础上制定,微软则于1990年代初期在成功移植BSD套接字的基础上开发了winsock[5],此外使用TCP/IP技术进行通信的各种嵌入式系统也有诸多基于Socket API的移植版本。

套接字是在文件I/O机制的基础上实现的,包括匿名和有名两种文件形式。典型的有名套接字是/dev/log,它使用的是Unix域套接字,守护进程syslogd(8)使用它和使用系统日志服务的客户进程通信。下面的内容除非特别注明,否则“套接字”特指匿名套接字。

用于分析TCP/IP协议的经典Unix工具包括netcat(1)和tcpdump(1)。前者被称为网络瑞士军刀,可以建立任意基于TCP/IP的网络连接并进行输入输出;后者可以把所在网络上的数据流转储到当前的标准输出,这些输出可通过管道线连接到一些文本过滤器之类的程序进行分析。

本章只讲述套接字的建立、设置、数据收发等基本接口。关于套接字机制与TCP/IP实现细节可参考:

  • TCP/IP Illustrated Volume 2: The Implementation

中文译名《TCP/IP详解 卷2:实现》。基于4.4 BSD-Lite的套接字机制讲述TCP/IP实现;

  • The Design and Implementation of 4.4BSD

中文译名《4.4 BSD 设计与实现》。讲述包括Sockets机制在内的4.4 BSD设计原理与实现细节;

  • Understanding Linux Network Internals

中文译名《深入理解Linux网络技术内幕》。包括Linux环境的网络实现细节及解决方案。暂无简体中文版。

关于TCP/IP协议及应用可参考:

  • TCP/IP Illustrated Volume 1: The Protocols

中文译名为《TCP/IP详解 卷1:协议》。讲述TCPIP协议族的体系结构及细节;

  • UNIX Network Programming

中文译名为《UNIX网络编程》。其中第二版分为两卷,第一卷The Sockets Networking API(中文译名:《套接口API》)讲述了Sockets编程的细节;

  • Internetworking With TCP/IP Vol Ⅲ:Client-Server Programming And Applications

中文译名为《用TCP/IP进行网际互联 第三卷:客户-服务器编程与应用》。讲述C/S程序设计的典型模型与应用;

  • RFC

RFC[6]是互联网技术的文献资料集,这些文件[7]通过编号排定,也有译为中文的RFC文档[8]

[更多...]


  • 交互数据流一般用于诸如远程登录程序等客户端的输入与服务器端输入与命令解析的回显等。如rlogin,telnet等,现在远程登录一般都用ssh安全方式代替。

交互数据流总是以小于最大报文长度的分组发送。

  • 交互数据流中一个问题就是小报文段传送的效率的问题(例如rlogin击键与远程端的回显),接收方采用时延来判断确认是否可以推迟发送,以减少报文段的数目。
  • Nagle算法要求一个TCP连接上最多只能有一个未被确认的小分组,在此分组的确认到达之前收集另外的小分组等待发送。这种算法的优越之处在于其自适应性:数据分组的发送跟确认到达的时间有关。
  • 局域网主机之间很少使用Nagle算法,广域网有时候也要禁用Nagle算法。

 

  • TCP的成块数据流通常采用滑动窗口协议进行流量控制,该协议允许发送方在停止并等待确认前可以连续发送多个分组。窗口即为TCP发送接收数据的缓冲区。发送缓冲区中的数据发送成功后从缓冲区中删除,接收缓冲区中的数据接收确认成功递交给应用层后也在缓冲区中删除。
  • 滑动窗口协议通过窗口的更新控制数据传输,窗口的更新有三种情况:

1. 窗口合拢:窗口的左端向右移动,在发送端表示窗口数据被发送,在接端则表示数据被确认;

2. 窗口张开:窗口的右端向右移动,表示接收端应用层进程读取经确认的数据从而释放缓冲区;

3. 窗口收缩:窗口的右端向左移动,RFC强烈建议不要使用这种方式。

  • 若窗口左端到达右端,称其为零窗口,表示一种缓冲区的饱和状态。
  • TCP接收端如果窗口宽度为零,在处理完数据释放缓冲后需要再次向发送端提供当前的窗口大小信息。
  • 窗口的大小影响着TCP的性能,对主机的吞吐量影响很大,服务器需要更大的窗口。
  • 许多TCP实现在窗口大小增加到两个最大报文段长度或者最大可能窗口的50%的时候,会向对方发送窗口更新的ACK;
  • 慢启动:发送方通过使用“拥塞窗口”实现慢启动,初始大小为1个报文段,此后每收到一个ACK,窗口大小就增加一个报文段,取拥塞窗口和对方通告窗口之间的最小值为发送上限。
  • 传送通道的容量=带宽时延乘积,即带宽x时延(RTT)。为理想的稳定状态下,传送通道上报文段的大小,接收端的通告窗口必须不小于这个数目。 

  • TCP作为运输层服务,和UDP最大的不同是它是一种面向连接的、可靠的字节流服务。大多数的互联网应用程序都使用TCP,如 http,ftp,telnet,smtp 等。

面向连接是指使用TCP某个应用的两端在交互数据前必须先建立一个TCP连接。

TCP的可靠性主要由以下方式体现:

  1. 分割应用数据为TCP认为最适合发送的块,称为报文段;
  2. TCP使用定时器以等待目的端对报文段的接收确认;
  3. TCP收到对方端的一个报文段后,会给对方发送一个接收确认;
  4. 通过校验和确认数据差错,若校验错误,丢弃数据,不发送接收确认;
  5. 把数据交给应用层前,对各报文段重新排序组织;
  6. 丢弃重复发送的数据;
  7. 流量控制,通过缓冲区实现。

TCP传输稳定的字节流,但不关心字节流数据类型是ASCII还是二进制。

TCP采用全双工通信。

  • TCP的首部(20个固定字节+选项):
16位源端口–16位目的端口–32位起始序号–32位确认序号 –4位首部长度–6位保留位(置0)–6位标志位–16位窗口大小–16位校验和–16位紧急指针 –选项

32位起始序号表示本报文段在第几个字节开始发送;

tcpdump的输出中还包括了下一个待发送的报文段的起始序号,

32位确认序号表示待接收的下一个报文段起始序号,即被确认的报文段的起始序号加上报文段长度,ACK标志位置位时有效;

标志位从高到低依次为:

  1. URG:紧急指针有效;
  2. ACK:确认位;
  3. PSH:通知接收方应马上把缓冲区接收到的全部数据递交给应用层的进程,而不再等待其它额外的数据,对这个标志的确认,窗口一般恢复到最大;
  4. RST: 连接复位,在异常状况下置位,例如端口不可达或者连接异常终止(如在telnet时用^D或者^C强行关闭程序);
  5. SYN:同步方式,用于建立连接;
  6. FIN:连接结束;

窗口用于流量控制,通知对方自己的缓冲区当前剩余情况;

校验和覆盖整个TCP报文段,包括首部和数据部分,采用算法与UDP类似,使用伪首部;

紧急指针在URG被置位时使用,它指向紧急数据的最后一个字节。

MSS(maximum segment size最大段长度)是较常用的TCP首部选项,用于管理每个TCP包的长度;其它可能的选项还包括窗口扩大因子、时间戳等。

  • TCP连接由4个元素唯一确定:源IP、源TCP端口、目的IP、目的TCP端口。
  • TCP的状态变迁

按照netstat的显示有以下的TCP状态:

CLOSED, LISTEN, SYN_RCVD, SYN_SENT, ESTABLISHED,
CLOSE_WAIT, LAST_ACK, FIN_WAIT_1, CLOSING, FIN_WAIT_2, TIME_WAIT

其中进入ESTABLISHED状态对应一个连接的建立,退出ESTABLISHED对应一个连接的终止;

TIME_WAIT的等待时间为2MSL,即最大段生存时间,因为连接终止前发起的一方可能需要重发ACK,所以停留在该状态的时间必须为MSL的2 倍。

  • TCP的建立

TCP的建立通过客户端与服务器端的三次握手实现。

  1. 客户端发出含SYN位的报文段,并指出要求连接的TCP端口和初始序号,同时更改状态为 SYN_SENT;
  2. 处于LISTEN状态的服务器作出响应,发送SYN和ACK,并给出确认序号,同时更改状态为 SYN_RCVD;
  3. 客户端确认服务器的响应,给出带确认序号的ACK段,同时更改状态为ESTABLISHED,服务器收到该响应后也更改状态为 ESTABLISHED。
  • TCP的终止

TCP的终止通过双方的四次握手实现。发起终止的一方执行主动关闭,响应的另一方执行被动关闭。

  1. 发起方更改状态为FIN_WAIT_1,关闭应用程序进程,发出一个TCP的FIN 段;
  2. 接收方收到FIN段,返回一个带确认序号的ACK,同时向自己对应的进程发送一个文件结束符EOF,同时更改状态为CLOSE_WAIT,发起方接到 ACK后状态更改为 FIN_WAIT_2;
  3. 接收方关闭应用程序进程,更改状态为LAST_ACK,并向对方发出一个TCP的FIN 段;
  4. 发起方接到FIN后状态更改为TIME_WAIT,并发出这个FIN的ACK确认。ACK发送成功后(2MSL内)双方TCP状态变为 CLOSED。
  • TCP的半关闭

指结束一方的数据传送,同时继续接收对方的数据。

  • TCP的半打开

一方连接关闭,另一方不知道。例如运行telnet的客户端断线或者意外停电,而在服务器上的这个连接还是打开的。

  • TCP的同时打开和同时关闭

同时打开需要双方确认对方的本地端口,

同时打开和同时关闭双方都是主动打开和主动关闭,而且需要几乎同时开始启动至少在收到对方的SYN或者FIN前就启动;

同时打开和同时关闭的握手过程和状态变迁略。

  • TCP服务器的设计:

一个服务器的任何进程都只能使用同一个TCP端口,但是允许使用不同接口 (IP)。

对于同一端口的多个连接请求使用连接队列处理,处理原则为FIFO,被TCP处理的连接在缓冲区中处理其命令或者数据传输。


6 UDP的上层:DNS、TFTP、BOOTP | 2006年10月05日

  • DNS域名系统是应用层协议,可以用于UDP或TCP,通常使用 UDP。

DNS的概念和功能见RFC 1034,DNS的规范和实现见RFC 1035。

  • DNS域名的层次结构类似于Unix文件系统,各个分支可以有名称相同的结点,但结点是唯一确定的,也可以用别名连接两个结点。
  • 顶级域名包括用于地址转换的arpa、3字节的组织域(.com, .org 等)、2字节的地理域(.cn, .uk等,地理代码基于ISO 3166)
  • IP到域名的转换转换查询通过DNS服务器的服务实现,DNS缓存并更新域名信息,与其他DNS主机使用分布式交互信息。DNS在UDP或者TCP的知名端口均为 53。
  • DNS服务器的根域为根服务器,由美国NIC负责管理或者委托授权。根服务器用于管理全球互联网上的IP分配、域名分配、DNS查询等。根服务器列表可以从NIC的ftp获取或者向nic@sri-nic.arpa发送邮件获取。
  • DNS服务器设置在/etc/resolv.conf,此配置文件也可能包含域名映射记录。
  • 查询DNS的命令:
host <主机名>
  • DNS报文包括首部、查询及三个RR资源记录信息组成。
  • 首部共12字节,格式为:
标识(2字节)–标志(2字节)–问题数(2字节)–资源记录数(2字节)–授权资源记录数(2字节)–附加资源记录数(2字节)

标志字段包括(从高位到低位):

  1. QR(1 bits):查询(0)和应答 (1);
  2. opcode(4 bits):标准查询(0)、反向查询(1)、服务器状态请求 (2);
  3. AA(授权回答,1 bits):
  4. TC(报文可截断,1 bits):为1则此位有效;
  5. RD(递归要求,1 bits):置0且被请求的DNS服务器没有授权回答,则返回能解答该查询的其他DNS服务器列表;
  6. RA(递归可用,1 bits):若DNS服务器支持递归查询,在响应中此位置 1;
  7. left 0 (3 bits):3位未使用,必须置 0;
  8. rcode (4 bits):通常设置为0(无错误)。若值为3表示域名错误,其值只能从授权DNS服务器返回。

问题数用于查询报文,通常为1,后面三个都为 0;

资源记录通常用于应答报文,回答至少为1,剩下两项可以为0或非 0;

  • DNS报文中查询部分的格式(长度不确定):
查询名:    在各子域名前包含其长度,并以0结束,
            如www.google.cn的报文中的格式应为 3www6google2cn0
类型:      大约有20种,最常用的是A,表示期望获得查询明的 IP;
            PTR表示获得一个IP对应的域名,等等。在host命令中可以用-t选项指明这个参数。
类别:      通常为1,表示为互联网IP地址。

*       DNS报文中的响应部分(均采用资源记录RR的格式)

域名:          格式于查询部分的查询明相同;
类型:          和查询的类型相同;
类别:          和查询的类别相同,通常是 1;
生存时间:      客户程序保留该记录的秒数,通常为2 天;
资源数据长度:  依赖于类型字段的值,如A类型(IP地址)则为 4;
资源数据:      如A类型(IP地址)则为4个字节的IP地址。
  • 一个例子

对域名www.google.com的查询,-t a表明查询类型为A

root@mjxian-ubuntu ~
# host -t a www.google.com
www.google.com is an alias for www.l.google.com.
www.l.google.com is an alias for www-china.l.google.com.
www-china.l.google.com has address 64.233.189.104

tcpdump监听的输出:

13:35:18.761306 IP ubuntu.1061 > dart.scu.edu.cn.domain:  60353+ A? www.google.com. (32)
13:35:18.762104 IP dart.scu.edu.cn.domain > ubuntu.1061:  60353 3/6/6 CNAME www.l.google.com.,[|domain]
13:35:18.762770 IP ubuntu.1062 > dart.scu.edu.cn.domain:  11166+ PTR? 39.32.115.202.in-addr.arpa. (44)
13:35:18.763252 IP dart.scu.edu.cn.domain > ubuntu.1062:  11166* 1/2/2 (140)

dart.scu.edu.cn则为所请求的DNS服务器,其IP为 202.115.32.39, 后缀domain表示采用DNS服务的知名端口 53。

第1行中60353为查询报文的标识,+号表示要求递归,A?表示查询类型,查询名字为www.163.com,报文长度 32。

第2行中3/3/6表示回答RR、授权RR和附加信息RR的数量。CNAME的意思是该域名用了别名指向,[|domain]暂时不明……

第3、4行是tcpdump监听对DNS发出的额外请求,如果采用-n选项则没有这两行。

第3行要求得到202.115.32.39的主机域名,这主要是要求知道发送第2行数据的IP属于哪个主机。

第4行为对第3行的回答,*号表示授权回答;

  • PTR指针查询

用于对于指定的IP,要求知道其域名。采用in-addr.arpa域名进行转换。

例如要查询202.115.32.129的主机域名,其在DNS中查询的名字则为129.32.115.205.in-addr.arpa。其转换一般由相关的socket函数完成。

采用in-addr.arpa域主要是为了可以用一个单独的DNS分支查询IP到主机的映射,而不用遍历整个DNS树(从com到net再到 org….)。

查询

root@mjxian-ubuntu ~
# host -t ptr 202.115.32.129
129.32.115.202.in-addr.arpa domain name pointer wjl.scu.edu.cn.

tcpdump的输出:

13:13:20.531126 IP ubuntu.1052 > dart.scu.edu.cn.domain:  17925+ PTR? 129.32.115.202.in-addr.arpa. (45)
13:13:20.531944 IP dart.scu.edu.cn.domain > ubuntu.1052:  17925* 1/2/2 (145)
  • TFTP和 BOOTP

用于无盘系统的引导,BOOTP比RARP更易于实现。略。


  • UDP用户数据报协议是工作在运输层的协议,其正式规范为RFC 768。

UDP没有应答机制,不保证可靠传输,不重发数据,由于速度快,常用于本地通信(局域网或主机上的环回接口)。

  • UDP的报文格式(封装在IP包内):
src port(16 bits)–dst port(16 bits)–UDP length(16 bits)–check sum(16 bits)–data (its length depends on socket API or TCP/IP’s kernel features)

端口为UDP协议的端口,协议已经由IP数据首部标出;

16位UDP长度包括数据部分;

校验和校验整个UDP首部和数据部分,也采用16 bits二进制反码和。如果UDP有奇数字节,常在最后填充0字节以满足16bits的整数倍;

校验和包括32位源IP和32位目的IP地址为伪首部;

UDP校验和是可选项,如果全为0则未打开校验和,RFC规定默认下打开。

  • IP分片

由于路径MTU的制约,UDP、TCP等协议的数据在IP封装后通常要进行分片。其分片的标识、标志和片偏移(其值以字节为单位)在IP首部指定。IP分片可能在主机上也可能在中间路由器上进行,它对UDP、TCP等上层协议是透明的。

如果需要分片但是IP的标志设置了不分片位,将引起MTU小于该包的路由上的TCMP IP未分片报文,报文提供了下一站的MTU。

通常可利用这种错误报文进行路径MTU的发现。例如可以修改traceroute程序,使分组长度等于出口路由的MTU,收到ICMP未分片报文后,按报文的下一站MTU值修改分组长度,如果该报文未含MTU值,则按自己的机制递增长度,直到得到最小MTU。

UDP本身也可以进行路径MTU发现,但是其原理书中说的不是很明白。

  • ICMP源站抑制差错

若主机或路由接收数据报的速度比其处理速度要快导致缓存溢出,可能会引发这种差错。

UDP很容易会引发这种差错,但是目前多数的实现只接收TCP的源站抑制差错报文而忽略UDP的差错报文。

  • UDP服务器的端口(port)和接口(interface)

通常每个指定的接口和端口只提供一个服务进程,其客户端请求通过FIFO队列进行处理。

如果有多个IP(接口),各自接口的相同端口都可以运行一个服务器进程。

远程服务器的同一个应用或许会提供多个接口和端口。但是本地进程在指定对远程的连接接口后将自动选择本地的接口地址。

  • 单播、广播和多播:

单播把数据报发送给单一主机;

广播把数据报发送给指定网络上的所有主机;

多播发送给指定的多个主机。

单播、广播和多播的概念仅用于UDP实现。

  • 广播地址的类型

受限广播地址:255.255.255.255,本主机所在本地网络的广播地址,例如我所在子网219.221.206.32的广播地址 219.221.206.63。

网络广播地址:A类、B类、C类的广播地址,网络号不变,主机号所有位置1。

子网广播地址:子网号不变,主机号所有位置1。可以通过子网地址跟子网掩码的逻辑或得到。

所有子网的广播地址:子网号和主机好所有位置1。可以使用所用C类地址跟子网地址及子网掩码的反码依次相或得到。

  • 广播的应用范围

需要应用程序支持广播,例如tftp就不支持广播。ping广播地址需要加上-b选项即可得到所ping网络上所有主机的响应。

如果广播地址不是本地网络,需要路由器配置的支持。

  • 多播

多播概念的引入是为了避免广播时网络中对此广播没有兴趣的主机的负载。

多播使用多播组,多播组使用的是D类地址。从224.0.0.0~239.255.255.255。

多播组也跟TCP/UDP端口一样使用知名地址(wellkown)的概念。由RFC给出。

多播可应用于视频会议、在线聊天室等。

  • 多播在单一物理网络上的实现相对比较简单,多播进程把所要发送的数据报发给多播IP地址,设备驱动程序把多播地址转换为相应的以太网地址往外发。接收进程通过以太网卡过滤接收多播帧。

多播地址到以太网地址的转换使用其低23位直接映射到相应以太网地址中。映射地址并不唯一,需要设备驱动程序或IP层提供多播数据报过滤功能。

  • 多播使用IGMP——Internet组管理协议作为其基本模块,用于为主机和路由实现同一物理网络上的多播提供支持。

4 IP选路及相关选路协议 | 2006年10月04日

  • 几个显示本机路由表的相关命令,主机路由表的复杂性取决于所连接网络的拓扑结构。

route,输出为

root@mjxian-ubuntu ~
# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
localnet        *               255.255.255.224 U     0      0        0 eth0
default         219.221.206.62  0.0.0.0         UG    0      0        0 eth0

netstat -r,输出为

root@mjxian-ubuntu ~
# netstat -r
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
localnet        *               255.255.255.224 U         0 0          0 eth0
default         219.221.206.62  0.0.0.0         UG        0 0          0 eth0

netstat -rn,输出为

root@mjxian-ubuntu ~
# netstat -rn
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
219.221.206.32  0.0.0.0         255.255.255.224 U         0 0          0 eth0
0.0.0.0         219.221.206.62  0.0.0.0         UG        0 0          0 eth0
  • IP选路策略:

先搜索匹配主机,再搜索匹配网络,最后搜索默认路由 (default)

  • 路由表中Flags的含义:
U       可用路由
G       该路由作为网关
H       该路由为主机地址(而不是网络地址)
D       该路由通过ICMP重定向得到
  • Metric字段,表示路由每一跳的度量。
  • 若IP无法到达目的地,出错的路由器将向源主机发送ICMP主机不可达或者网络不可达差错报文。
  • ICMP重定向:

在主机有多个路由出口时,收到IP数据报的默认路由器识别到从主机开始,另有最佳路由,将向源主机发送ICMP重定向报文,修改更新源主机上的路由表。

  • ICMP路由发现请求/应答报文:

主机对TCP/IP网络进行初始化时向路由器发送ICMP请求,路由器进行应答,发送ICMP路由器通告报文。同时路由器也不定期向网络上的广播或多播地址发送路由通告,主机进行监听。这些工作通过Unix的守护进程实现。

  • 动态选路:

路由器的动态选路策略通过守护进程实现。quagga是一个提供RIP/OSPF/BGP选路管理的实用程序。守护进程在前往同一信宿有多个路由时可以以某种策略选择最佳路由并更新路由表,同时也可以在链路断开时删除该路由或者新增一条。

用于动态选路的选路协议包括IGP和EGP,内部网关或者外部网关协议。


  • RIP动态选路信息协议:

RIP的正式规范见RFC 1058。

RIP是一种IGP,是基于距离向量的选路协议。距离向量意味着RIP的报文包含了IP的跳数(距离向量)。

RIP使用了UDP,封装在UDP数据报内传送。接收端(server)的UDP端口为 520

RIP的首部格式(4 bytes):

cmd(8 bits,value:1~6)–version(8 bits)–left 0 (16 bits)

每个路由信息的数据格式(20 bytes):

address family(16 bits)–left 0(16 bits)–IP address(32 bits)–left 0(32 bits)–left 0(32 bits)–metric(32 bits, value<16)

一共可以使用25个路由。使总数 4 + 25 x 20 = 504 < 512   (bytes)

  • 使用RIP的守护进程的主要任务:

初始化,请求发送完整路由表求。RIP作为发送完整路由表请求时,cmd值为1,地址族置0,metric置16,总长度为24字节。

响应时按照格式填入报文,发送给请求端。metric为跳数,以请求主机为起点,如果没有目的主机,metric设置为16。收到响应可能会更新路由表使响应生效。

正常工作时,路由器通过广播或者点对点链路定时向其它路由器发送完整的路由表。

如果有一条路由的metric发生变化,发送该路由的RIP报文给其它主机进行更新。收到报文的路由按照metric最小的策略选择更新自己的路由表。 metric的最大值为15,为16时表明该IP无法到达。

  • RIP的缺点:
  1. 不支持子网;
  2. 路由器或链路发生故障后,网络在稳定前可能会发生路由环路错误。
  3. metric<16限制了使用RIP的网络规模。
  • RIP-2

RIP的扩充版本,定义了原RIP包中一些置零的字段。如下:

首部格式(4 bytes):

cmd(8 bits,value:1~6)–version(8 bits)–routing domain (16 bits)

每个路由信息的数据格式(20 bytes):

address family(16 bits)–routing tags(16 bits)–IP address(32 bits)–netmask(32 bits)–next IP address(32 bits)–metric(32 bits, value<16)

routing domain:一般定义为选路守护进程的 pid;

routing tag:   对EGP支持的扩充;

RIP-2扩充了对多播的支持,以减少不监听RIP-2报文的主机的负载。


  • OSPF协议

也是一种IGP协议,其正式规范见RFC 1247,它是基于链路状态的选路协议。

使用OSPF的路由器主动测试与邻站的连接状态,并把状态信息发到其它邻站,通过这样的一种交互更新各自的路由表。

  • OSPF的特点:

使用IP而不是 TCP/UDP;

每个IP服务类型都可以有一套自己的路由集,即使目的地址一样;

管理各IP服务类型的费用和流量平衡;

支持子网;

采用多播而不是广播,以减少不参与OSPF的系统负载。


  • BGP边际网关协议

一种EGP协议,基于距离向量。略。


3 ICMP协议及应用 | 2006年10月02日

  • ICMP:Internet控制报文协议

用于为IP或者更高层协议传递查询/请求/差错相关报文,封装在IP数据报内部。其规范见RFC 792。

  • 发送网络广播不会引起ICMP差错报文。
  • ICMP报文的主要格式:
类型(8位)–代码(8位)–校验和(16位)–报文内容

类型共15种,其值为0~18,但不包括1、2、6、 7;

代码字段从0~15共16种。类型字段和代码字段共同组成定义了ICMP的报文类型。

检验和算法与IP首部相同,即全部取反,然后每16位累加。覆盖整个ICMP报文。

  • ICMP掩码地址请求与应答报文(共12字节):

用于无盘系统在引导过程中获取自己的子网掩码。

格式:

类型(Req=17/Ack=18)–代码(0)–校验和–标识符(2 bytes)–序号(2 bytes)–Netmask(32 bits)

由IP往广播地址发送,应答主机把响应传回给请求主机。

  • ICMP时间戳请求与应答报文(20字节):

用于一台主机向另一台主机查询当前时间。时间戳的建议值为UTC从0时开始计算的时间,单位为毫秒。

格式:

类型(Req=17/Ack=18)–代码(0)–校验和–标识符(2 bytes)–序列号(2 bytes)–
发起时间戳(32 bits)–接收时间戳(32 bits)–传送时间戳(32 bits)

请求时只填写发起时间戳。大多数实现在响应时把接收和传送时间戳填写为相同的值。

与请求主机的时钟的差别的算法(单位: 毫秒):

(接收时间戳-发起时间戳)-(发请求的时间-收到响应的时间)/2

即先比较响应主机接收到请求报文时的时间与发起的差,再减去网络往返的时间。

  • ICMP端口不可达差错报文:

一种常见的ICMP差错。

格式:

类型(3)–代码(0~15)–校验和–未用(32 bits,必须为 0)–IP首部–原始IP数据报中数据的前8个字节

类型3为各种ICMP不可达报文,共16 种。

IP首部用于为出错主机提供协议字段,从而分析往后的8个字节,而后8个字节包含了TCP或者UDP等协议的源端口和目的端口,从而使出错主机可以从端口号把差错报文与相关的进程关联起来。

注:ICMP规范允许IP数据报中的数据多于8个字节,但大多BSD的派生系统只返回8个字节。


  • ping程序
  • ping是ICMP最常见的应用,使用的是ICMP回显请求/应答报文,而不必经过TCP/UDP的传输层。
  • ICMP回显请求/应答报文的格式:

        类型(Req=8/Ack=0)–代码(0)–校验和(16 bits)–标识符(16 bits)–序号(16 bits)–选项数据

  • ping局域网的另一台主机的输出:
root@mjxian-ubuntu ~
# ping 219.221.206.53
PING 219.221.206.53 (219.221.206.53) 56(84) bytes of data.
64 bytes from 219.221.206.53: icmp_seq=1 ttl=64 time=5.12 ms
64 bytes from 219.221.206.53: icmp_seq=2 ttl=64 time=0.727 ms
64 bytes from 219.221.206.53: icmp_seq=3 ttl=64 time=0.730 ms
64 bytes from 219.221.206.53: icmp_seq=4 ttl=64 time=0.756 ms
64 bytes from 219.221.206.53: icmp_seq=5 ttl=64 time=0.743 ms

— 219.221.206.53 ping statistics —
5 packets transmitted, 5 received, 0% packet loss, time 4016ms
rtt min/avg/max/mdev = 0.727/1.615/5.120/1.752 ms

第一个往返时间比后面的要大,一般是由于包含了局域网上arp请求与应答的时间。如果arp -a看到目标主机已经在本机的arp高速缓存上,就不用再进行arp请求。

以下是tcpdump在局域网上抓包的结果,显然是每秒发送和接收一次ICMP回显:

11:27:12.587877 arp who-has 219.221.206.53 tell ubuntu
11:27:12.588589 arp reply 219.221.206.53 is-at 00:14:78:d4:f1:43 (oui Unknown)
11:27:12.588612 IP ubuntu > 219.221.206.53: ICMP echo request, id 17432, seq 1,length 64
11:27:12.589342 IP 219.221.206.53 > ubuntu: ICMP echo reply, id 17432, seq 1,length 64
11:27:13.587972 IP ubuntu > 219.221.206.53: ICMP echo request, id 17432, seq 2,length 64
11:27:13.588667 IP 219.221.206.53 > ubuntu: ICMP echo reply, id 17432, seq 2,length 64
11:27:14.592023 IP ubuntu > 219.221.206.53: ICMP echo request, id 17432, seq 3,length 64
11:27:14.592724 IP 219.221.206.53 > ubuntu: ICMP echo reply, id 17432, seq 3,length 64
11:27:15.596088 IP ubuntu > 219.221.206.53: ICMP echo request, id 17432, seq 4,length 64
11:27:15.596814 IP 219.221.206.53 > ubuntu: ICMP echo reply, id 17432, seq 4,length 64
11:27:16.600304 IP ubuntu > 219.221.206.53: ICMP echo request, id 17432, seq 5,length 64
11:27:16.601015 IP 219.221.206.53 > ubuntu: ICMP echo reply, id 17432, seq 5,length 64
  • ping非本局域网上的一台主机的输出

例如校园网里面的www.wjl.cn,其结果如下。很显然这次第一次返回并没有很大的时间差,这是因为由于wjl.scu.edu.cn这台主机并不在局域网内,封装ICMP的IP数据报直接投递给路由,后面的事情由路由解决,看起来应该是这台机器的硬件地址已经在某台路由上的arp高速缓存里面了,省去了arp请求的一步。

root@mjxian-ubuntu ~
# ping www.wjl.cn
PING www.wjl.cn (202.115.32.129) 56(84) bytes of data.
64 bytes from wjl.scu.edu.cn (202.115.32.129): icmp_seq=1 ttl=62 time=0.368 ms
64 bytes from wjl.scu.edu.cn (202.115.32.129): icmp_seq=2 ttl=62 time=0.395 ms
64 bytes from wjl.scu.edu.cn (202.115.32.129): icmp_seq=3 ttl=62 time=0.261 ms
64 bytes from wjl.scu.edu.cn (202.115.32.129): icmp_seq=4 ttl=62 time=0.345 ms
64 bytes from wjl.scu.edu.cn (202.115.32.129): icmp_seq=5 ttl=62 time=0.324 ms
64 bytes from wjl.scu.edu.cn (202.115.32.129): icmp_seq=6 ttl=62 time=0.382 ms
64 bytes from wjl.scu.edu.cn (202.115.32.129): icmp_seq=7 ttl=62 time=0.423 ms
64 bytes from wjl.scu.edu.cn (202.115.32.129): icmp_seq=8 ttl=62 time=0.250 ms
64 bytes from wjl.scu.edu.cn (202.115.32.129): icmp_seq=9 ttl=62 time=0.428 ms

— www.wjl.cn ping statistics —
9 packets transmitted, 9 received, 0% packet loss, time 8034ms
rtt min/avg/max/mdev = 0.250/0.352/0.428/0.065 ms

这是tcpdump抓包的结果 (略):

11:36:43.053719 IP ubuntu > wjl.scu.edu.cn: ICMP echo request, id 26713, seq 1,length 64
11:36:43.054048 IP wjl.scu.edu.cn > ubuntu: ICMP echo reply, id 26713, seq 1,length 64
11:36:44.059846 IP ubuntu > wjl.scu.edu.cn: ICMP echo request, id 26713, seq 2,length 64
11:36:44.060206 IP wjl.scu.edu.cn > ubuntu: ICMP echo reply, id 26713, seq 2,length 64

ping输出的ttl是62,是由于经过了2次路由,减了2,一个简单的路由查询可以使用ping -R选项。它显示了一次请求和应答整个往返过程经过的所有路由。

  • ping -R 目标主机,显示往返所经路径。

-R选项要求返回的IP数据报的首部操作选项包含RR路由记录。这要求路由提供IP数据报的R操作R选项支持,下例中,经过的两个路由都没有显示出来,说明这些路由都不支持RR选项。

root@mjxian-ubuntu ~
# ping -R www.wjl.cn
PING www.wjl.cn (202.115.32.129) 56(124) bytes of data.
64 bytes from wjl.scu.edu.cn (202.115.32.129): icmp_seq=1 ttl=62 time=1.20 ms
RR:     ubuntu (219.221.206.48)
        wjl.scu.edu.cn (202.115.32.129)
        wjl.scu.edu.cn (202.115.32.129)
        ubuntu (219.221.206.48)

64 bytes from wjl.scu.edu.cn (202.115.32.129): icmp_seq=2 ttl=62 time=1.20 ms (same route)
64 bytes from wjl.scu.edu.cn (202.115.32.129): icmp_seq=3 ttl=62 time=1.14 ms (same route)
64 bytes from wjl.scu.edu.cn (202.115.32.129): icmp_seq=4 ttl=62 time=2.49 ms (same route)
64 bytes from wjl.scu.edu.cn (202.115.32.129): icmp_seq=5 ttl=62 time=1.09 ms (same route)
64 bytes from wjl.scu.edu.cn (202.115.32.129): icmp_seq=6 ttl=62 time=1.12 ms (same route)
64 bytes from wjl.scu.edu.cn (202.115.32.129): icmp_seq=7 ttl=62 time=1.10 ms (same route)
64 bytes from wjl.scu.edu.cn (202.115.32.129): icmp_seq=8 ttl=62 time=1.10 ms (same route)
64 bytes from wjl.scu.edu.cn (202.115.32.129): icmp_seq=9 ttl=62 time=1.07 ms (same route)

— www.wjl.cn ping statistics —
9 packets transmitted, 9 received, 0% packet loss, time 8068ms
rtt min/avg/max/mdev = 1.074/1.282/2.491/0.432 ms

使用ping -R,就是要求返回的IP数据报的首部操作选项包含RR路由记录,

  • RR操作的IP选项主要格式为
code(RR=7,1 bytes)–len(1 bytes)–ptr(1 bytes)–addr1(4 bytes per addr#)

其中ptr为addr的指针,从4开始;

addr一共最多可以记录9个,因为一个IP选项字段最多可以存放40字节。

用tcpdump -v查看的输出如下:包含了IP首部和操作选项:

12:08:05.985310 IP (tos 0×0, ttl  64, id 0, offset 0, flags [DF], proto: ICMP(1), length: 124, options ( NOP (1) len 1 )) ubuntu > mail.scu.edu.cn: ICMP echo request, id 42296, seq 1, length 64
12:08:05.986331 IP (tos 0×0, ttl  62, id 24203, offset 0, flags [none], proto: ICMP (1), length: 124, options ( RR (7) len 39ubuntu, mail.scu.edu.cn, mail.scu.edu.cn, 0.0.0.00.0.0.00.0.0.00.0.0.00.0.0.00.0.0.0EOL (0) len 1 ))mail.scu.edu.cn > ubuntu: ICMP echo reply, id 42296, seq 1, length 64

第一个为 ICMP echo request, IP首部不包含操作选项(NOP,无操作)

第二个为 ICMP echo reply,记录了路由上的主机地址,后面空的填充为0,EOL表示操作选项清单结束。

  • IP时间戳选项: 
ping -T tsonly/tsandaddr/tsprespec  host1 [host2 [host3[host4]]] 目标主机
        tsonly          选项只显示时间戳 (timestamp)
        tsandaddr       包括每个路由上的主机名和时间戳
        tsprespec       预指定要显示时间戳的路由,最多4 个。

时间戳记录为UTC时间午夜00时至今的时间,单位毫秒。


  • traceroute程序
  • traceroute是使用ICMP报文的另一个重要应用程序。它还利用了这样一个事实,就是IP数据报里面的TTL字段每经过一个路由都将自动减1,如果在路由内停留超过1秒则减去这个秒数。事实上TTL在今天已经用来作为路由计数器,每一跳减1,到为0时该IP数据报即被丢弃,然后路由返回一个 ICMP超时出错报文。

traceroute程序运行后每次往目标主机反复发送3次一个带UDP数据的IP数据报,其TTL初始值为1,收到ICMP超时报文后再发一个,然后再发3次一个TTL值为2的报文。直到抵达目的主机。而UDP数据里面的目的端口设置为不可能的UDP端口,Unix的实现一般用traceroute的 pid | 32768,这样traceroute通过查询返回的ICMP出错报文是超时还是端口不可达判断是下一跳路由或者是目的主机。

  • 下面是一个用traceroute命令查看到主机wjl.scu.edu.cn的例子。和上面ping -R wjl.scu.edu.cn 用ping来查看路由比较,会发现ping -R的输出并不包含219.221.206.62这台路由,可能是路由不支持IP操作选项的RR特性的缘故。而trceroute利用的是ICMP的出错报文,只要求路由支持ICMP和目的主机支持UDP就可以了。另外两个tracerouteping -R更好用的原因是ping -R显示的是往返路由,且其长度受IP首部所限最多只能记录9个路由。而traceroute显示的是单向路由,显示的路由数能达到TTL规范的最大值。
root@mjxian-ubuntu ~
# traceroute wjl.scu.edu.cn
traceroute to wjl.scu.edu.cn (202.115.32.129), 30 hops max, 40 byte packets
 1  219.221.206.62 (219.221.206.62)  0.992 ms  0.656 ms  0.539 ms
 2  10.10.34.2 (10.10.34.2)  0.609 ms  0.596 ms  0.482 ms
 3  wjl.scu.edu.cn (202.115.32.129)  0.548 ms  0.312 ms  0.314 ms

前面的序号,和所发送的TTL值一次,第一个值比较大,为0.992 ms,一般认为是arp交换或者向dns服务器查询域名等其它预处理的原因。可见到主机wjl.scu.edu.cn共经过了2个路由,这一点也可以从 ping的时候看到TTL为62看得出来。

  • 以下为traceroute执行时用tcpdump的抓包输出。可见主机ubuntu一直在向wjl.scu.edu.cn发送一个包括12字节数据的 UDP包,每个经过的路由都发了三次,而路由也返回三次长度为36字节的ICMP超时报文,最后是主机wjl.scu.edu.cn发送三次端口不可达报文。UDP端口是每发一次自动加1,初始值由traceroute进程的pid和32768相或得到。该进程pid可以在程序运行时通过ps -A显示出来。
16:53:25.799438 IP ubuntu.40890 > wjl.scu.edu.cn.33435: UDP, length 12
16:53:25.800050 IP 219.221.206.62 > ubuntu: ICMP time exceeded in-transit,length 36
16:53:27.391779 IP ubuntu.40890 > wjl.scu.edu.cn.33436: UDP, length 12
16:53:27.392342 IP 219.221.206.62 > ubuntu: ICMP time exceeded in-transit,length 36
16:53:27.392808 IP ubuntu.40890 > wjl.scu.edu.cn.33437: UDP, length 12
16:53:27.393262 IP 219.221.206.62 > ubuntu: ICMP time exceeded in-transit,length 36
16:53:27.394112 IP ubuntu.40890 > wjl.scu.edu.cn.33438: UDP, length 12
16:53:27.394619 IP 10.10.34.2 > ubuntu: ICMP time exceeded in-transit, length 36
16:53:28.963890 IP ubuntu.40890 > wjl.scu.edu.cn.33439: UDP, length 12
16:53:28.964418 IP 10.10.34.2 > ubuntu: ICMP time exceeded in-transit, length 36
16:53:28.964837 IP ubuntu.40890 > wjl.scu.edu.cn.33440: UDP, length 12
16:53:28.965257 IP 10.10.34.2 > ubuntu: ICMP time exceeded in-transit, length 36
16:53:28.966022 IP ubuntu.40890 > wjl.scu.edu.cn.33441: UDP, length 12
16:53:28.966489 IP wjl.scu.edu.cn > ubuntu: ICMP wjl.scu.edu.cn udp port 33441 unreachable, length 48
16:53:28.967881 IP ubuntu.40890 > wjl.scu.edu.cn.33442: UDP, length 12
16:53:28.968127 IP wjl.scu.edu.cn > ubuntu: ICMP wjl.scu.edu.cn udp port 33442 unreachable, length 48
16:53:28.968541 IP ubuntu.40890 > wjl.scu.edu.cn.33443: UDP, length 12
16:53:28.968792 IP wjl.scu.edu.cn > ubuntu: ICMP wjl.scu.edu.cn udp port 33443 unreachable, length 48
  • traceroute-g -G选项

-g-G选项为自定义源站选路的选项,traceroute命令必须经过该选项指定的路由,其中-G严格指定了要经过的全部路由顺序,-g只指定必须要经过的路由顺序。

我机器上的traceroute的版本为1.4a12,从源代码来看已经取消了-G选项。

-g选项一个有用的应用是可以查看到某主机往返的路由是否一致,只需把目的主机设为-g指定的主机,把发出主机设为tracert的最终主机。这时 traceroute就先查找从发出主机srchost到dsthost的路由,再查找dsthost到srchost的路由。完成一次从 localhost到dsthost的往返。

traceroute -g dsthost srchost


  • IP网际协议:

负责数据报从源地址传给目的地址,提供的是非可靠、无连接的传送服务,所有可靠性和包装需要通过上层协议如TCP来提供。

  • IP首部格式:

每32 bits一组,共5组(20个字节)

第一组:

Version(4 bits)–HeadLength(4 bits)–TOS(8 bits)–TotalLength(16 bits)
  IPv4/IPv6     一般为5(按32位计算)              IP包总长(<65535 bytes)

TOS字段包括:   

优先级(3位,现代已经忽略)–0(未用)–TOS 值

        TOS值1位置1,3位置0,分别表示:

0×10(最小时延) 0×08(最大吞吐量) 0×04(最高可靠性) 0×02(最小费用)

现在大多数应用程序都不支持TOS特性。

第二组:

标识(16 bits)–标志(3 bits)–片偏移(13 bits)

第三组:

TTL(8 bits)–Protocol(8 bits)–Head Sum (16 bits)
        32/64        TCP/UDP/ICMP

首部校验和的算法:首部校验和位置零,20个字节全部取反码,每16位一组求和。

计算校验和的技术见RFC 1071,接收方计算结果如果不是全1,则认为传输出错。

第四组:源IP地址;

第五组:目的IP地址。

  • IP路由选择:    通过路由表。

路由类型:     

目标主机 > 目标网络 > 默认下一个路由 (转发数据的优先级)

在IP数据报传输中,32位的IP地址始终不变,而链路层的数据封装格式和48位的以太网地址由链路层协议确定,每站路由都可能会发生改变,其中封装格式有以太网/SLIP/PPP等(见链路层相关笔记),以太网地址为下一个路由的以太网地址。

  • A类地址、B类地址、C类地址的概念。子网的划分。
子网地址 = IP地址 <and> 子网掩码
广播地址 = 子网地址 <or> !子网掩码
  • 查看接口IP地址、子网掩码、广播地址、MTU的命令:netstatifconfig 等。

  • ARP地址解析协议:

用于在32位的IP地址与对应的硬件地址(以太网地址)之间建立映射。内核(如以太网驱动程序)必须知道硬件地址才能发送数据。

  • 发送IP数据报前,先广播发送一个ARP请求的数据帧,以获得ARP应答,应答包含目的IP地址及其硬件地址。
  • 点对点链路只需要知道两端的IP地址,不涉及硬件地址,不需要 ARP;
  • ARP的帧格式(42字节,其中前14个字节为以太网数据帧的首部):
以太网目的地址(6字节)–以太网源地址(6字节)–帧类型(2字节)–硬件地址类型(2字节)–协议类型(2字节)–硬件地址长度(1字节)
–协议地址长度(1字节)–操作类型(2字节)–发送端以太网地址(6字节)–发送端IP地址(4字节)–目的以太网地址(6字节)–目的 IP地址(4字节)

硬件地址类型:为1表示为以太网地址;

协议类型:为0×8000表示为IP协议(和以太网数据帧的首部帧类型相同定义);

硬件地址长度:以太网地址的值为 6;

协议地址长度:IP地址为 4;

操作类型:1: ARP请求;2: ARP应答;3: RARP请求;4: RARP应答。

发送端、目的以太网地址与以太网帧的首部12个字节相同,而目的以太网地址在发出ARP请求时所有位置1,表示为广播地址。

  • ARP代理(proxy ARP):

通过路由应答不同网络上的ARP请求,把路由的以太网地址发送给源主机。源主机端认为该路由的以太网地址就是所求地址,从而开始向该路由器发送IP数据报。

  • 免费ARP(gratuitous ARP):

发送自己IP地址的ARP请求。用于确定是否和别的主机产生IP冲突,或者用于更新网络上其他主机的相应的ARP高速缓存。

  • ARP相关命令:
$ arp -a                        查看ARP高速缓存;
$ arp -d [host]                 在ARP高速缓存中删除指定项;
$ arp -s [host] [hwaddr]        在ARP高速缓存中增减指定项。
  • tcpdump命令所监听到的ARP查询和应答一例:
11:44:33.865795 arp who-has 219.221.206.62 tell ubuntu
11:44:33.866219 arp reply 219.221.206.62 is-at 00:09:97:07:d6:06 (oui Unknown)

第一行发出广播,查询IP地址219.206.62的以太网地址,并要求返回给主机 ubuntu

第二行收到应答。

附:     水木社区关于ARP的讨论的一个小结。

发信人: cheyo (cheyo), 信区: Networking
标  题: Re: 请教ARP:当目标主机与源主机不在同一网段时
发信站: 水木社区 (Tue Jan 10 00:25:13 2006), 转信

嗯。改了一下下:

    在底层网络中,两台主机之间的通信需要知道源主机与目标主机的Mac地址。ARP缓存
表记录了本网段中IP地址与Mac地址的映射关系。
    当源主机与目标主机处在同一网段时,源主机首先查询本机的ARP缓存表,如果在该
表中可以查询到目标主机的Mac地址,则直接发送数据,否则源主机向同一网段的所有节
点发送广播,同一网段的所有主机都会接收到该广播,但只有目标主机会响应并告知源主
机其Mac地址。于是源主机把目标主机的IP与Mac地址记录到ARP缓存表中,并通过该Mac地
址发送数据。
    如果源主机与目标主机不在同一网段,则源主机在本机路由表中查询源主机到达目标
网络需要通过哪一个网关,然后与"源主机与目标主机处在同一网段"类似的,源主机先取
得该网关的Mac地址,然后本地主机将数据帧提交给网关。之后,由网关判断下一跳的主机
地址或者网络地址。


  • RARP    用于无盘系统/工作站在引导时获取IP地址。分组格式和ARP一致。

  • 链路层的功能:
  1. 为IP模块发送和接收IP数据报;
  2. 为ARP模块发送ARP请求和接收ARP应答;
  3. 为RARP发送RARP请求和接收RARP应答
  • 以太网IP数据报的封装定义在RFC 894中。
  • IP地址(32位)通过ARP映射到以太网地址(48位);
  • 以太网帧格式:
dest(6 bytes)–src(6 bytes)–type(2 bytes)–data(46~1500 bytes)–CRC(4 bytes)
 48 bits        48 bits       0800 (IP)
                              0806 (ARP)  28 bytes (R/A)-18 bytes(PAD)
                              8035 (RARP) as above
  • SLIP (串行线路IP,电话拨号等串行数据传输时使用):

END-数据-END        如果数据里含END,需要转义。

  • PPP(点对点协议),包括
1)串行线路上封装IP数据报的方法;              
                                                 RFC 1548
2)建立、配置、测试数据链路的链路控制协议LCP;  /
3)针对不同网络层协议的网络控制协议 NCP;       —RFC 1332

PPP数据侦格式(十六进制,两位表示一个字节):

标志(7E)–地址(FF)–控制(03)–协议(2字节)–信息(<1500字节)–CRC(2字节)-标志(7E)
                              0021 (IP)
                              c021 (LC)
                              8021 (NC)

信息段如果含0x7e(标志字段的值),需要转义,转义字符为0x7d,同时原值第六位取补码。如

0x7e –> 0x7d + 0x5e
0x7d –> 0x7d + 0x5d

原则上<0×20的值(ASCII控制字符之类)都要进行转义。

  • 环回接口(127.0.0.1 localhost):用于同一台主机上C/S的TCP/IP通信,
  • MTU最大传输单元:链路层的数据侦长度上限,各种网络的典型MTU值见RFC 1191
  • 路径MTU:两台通信主机路径中的最小MTU,由于取决于所选路由,故不是常数。

RFC1191描述了路径MTU的发现机制,即在任何时候确定路径MTU的方法。

  • $ netstat -i    查看主机接口及其MTU