首页 > 代码库 > 《TCP/IP详解》
《TCP/IP详解》
Transmission Control Protocol/Internet Protocol的简写,中译名为传输控制协议/因特网互联协议,又名网络通讯协议,是Internet最基本的协议、Internet国际互联网络的基础,由网络层的IP协议和传输层的TCP协议组成。TCP/IP 定义了电子设备如何连入因特网,以及数据如何在它们之间传输的标准。协议采用了4层的层级结构,每一层都呼叫它的下一层所提供的协议来完成自己的需求。通俗而言:TCP负责发现传输的问题,一有问题就发出信号,要求重新传输,直到所有数据安全正确地传输到目的地。而IP是给因特网的每一台联网设备规定一个地址。
TCP/IP通常被认为是一个四层协议:
-
链路层。也称数据链路层或网络接口层,包括设备驱动程序和网络接口卡,它们一起处理与电缆的物理接口细节。
-
网络层。处理分组在网络中的活动,如分组的选路;网络层的协议包括IP协议、ICMP协议(Internet互联网控制报文协议)、IGMP协议(Internet组管理协议)。
-
传输层。主要为两台主机上的应用程序提供端到端的通信,包括TCP(传输控制协议)和UDP(用户数据报协议)。
-
应用层。处理特定的应用程序细节。
TCP/IP协议族中不同层次的协议如下:
互联网上的每个接口必须有唯一的IP地址,5类不同的IP地址格式和返回如下:
当应用程序用TCP传送数据时,数据被送入协议栈,然后逐个通过每一层直到被当作一串比特流送入网络,其中每一层对收到的数据都要增加一些首部信息。
链路层
链路层主要有三个目的:
-
为IP模块发送和接受IP数据;
-
为ARP模块发送ARP请求和接受ARP应答;
-
外RARP发送RARP请求和接受RARP应答。
环回接口
环回接口允许运行在同一台主机上的客户程序和服务器程序通过TCP/IP进行通信,IP地址127.0.0.1被分配给这个接口,并命名为localhost。
目的地址的环回地址时,照样还是传输层和网络层的所有过程,只是当IP数据报离开网络层时把它返回给自己,这样做简化了设计,因为环回接口可以看作是网络层下面的一个链路层。网络层把一份数据报传送给环回接口,就像传送给其它链路层一样,只不过环回接口把它返回到IP的输入队列中。
MTU
以太网对数据帧的长度有一个限制,最大值是1500。链路层的这个特性称作MTU(最大传输单元)。如果IP层数据报的长度比链路层的MTU还要大,那么IP层就需要进行分片,每一片都要小于MTU。
如果两台主机之间的通信要通过多个网络,那么每个网络的链路层就可能有不同的MTU。两台通信主机路径中的最小MTU,被称为路径MTU。两个方向上的选路不一定对称,因此路径MTU在两个方向上不一定是一致的。
IP协议
IP是TCP/IP协议族中最为核心的协议。所有的TCP、UDP、ICMP及IGMP数据都以IP数据报格式传输。
IP提供不可靠、无连接的数据服务。不可靠的是指它不能保证IP数据报能成功地到达目的地;无连接是指IP并不维护任何关于后续数据报的状态信息,每个数据报的处理是相互独立的。
IP数据报格式
IP数据报格式如下图所示,普通的IP首部长为20字节,除非含有选项字段。
总长度字段是指整个IP数据报的长度,该字段长16位,所以IP数据报的最大长度为65535字节。
最后一个字段是任选项,是数据报中的一个可变长的可选信息,如记录路径、时间戳等,这些选项一般很少使用。
IP路由选择
IP路由选择是简单的,对于主机来说,如果目的主机与源主机直接相连或都在一个共享网络上,那么IP数据报就直接送到目的主机上;否则主机九堡数据报发往一默认的路由器上,由路由器来转发该数据报。
IP层既可以配置成路由器的功能,也可以配置成主机的功能。IP层在内存中有一个路由表,当收到一份数据报并进行发送时,它都要对该表搜索一次。当数据报来自某个网络接口时,IP首先检查目的IP地址是否为本机的IP地址之一或者IP广播地址。如果是的话,数据报就被送到由IP首部协议字段所指定的协议模块进行处理。如果数据报的目的不是这些地址,如果IP层被设置为路由器的功能,那么就对数据报进行转发,否则数据报被丢弃。
IP路由选择是逐跳进行的,IP并不知道到达任何目的的完整路径,所有IP路由选择只为数据报传输提供下一站路由器的IP地址。IP路由选择主要完成这些功能:
-
搜索路由表,寻找能与目的IP地址完全匹配的表目。
-
搜索路由表,寻找能与目的网络号相匹配的表目。
-
搜索路由表,寻找标为"默认"的表目。
如果上面的步骤都没有成功,数据报就不能被传送。
子网寻址
现在所有主机都要求支持子网编址。不是把IP地址看成单纯的一个网络号和一个主机号组成,而是吧主机号再分成一个子网号和一个主机号。
主机通过子网掩码来确定IP地址多少位用于子网号,多少位用于主机号。子网掩码是一个32位的值,值为1的位留给网络号和子网号,为0的位留给主机号。
给定IP地址和子网掩码以后,主机就可以确定IP数据报的目的是:(1)本子网上的主机;(2)本网络中其它子网的主机;(3)其它网络上的主机。
ICMP
ICMP(Internet控制报文协议)是IP层一个组成部分,它传递差错报文以及其他需要注意的信息,ICMP报文通常被IP层或更高层协议(TCP或UDP)使用,一些ICMP报文把差错报文返回给用户进程。ICMP是在IP数据报内部被传输的。
ICMP的一个规则是,ICMP差错报文必须包括生成该差错报文的数据报IP首部,还必须至少包括跟在该IP首部后面的前8个字节。这样就包含了UDP的首部,接收ICMP的系统就可以根据源端口号来把差错报文与某个特定的用户进程相关联。
Ping
Ping程序目的是为了测试另一台主机是否可达。该程序发送一份ICMP回显请求报文给主机,并等待返回ICMP回显应答。Ping程序还能测出到这台主机的往返时间。大多数的TCP/IP实现都在内核中直接支持Ping服务,这种服务器不是一个用户进程。
Ping程序通过在ICMP报文数据中存放请求的时间值来计算往返时间。当应答返回时,用当前时间减去存放在ICMP报文中的时间值,既是往返时间。
Traceroute
Traceroute程序可以让我们看到IP数据报从一台主机传到另一台主机所经过的路由,Traceroute程序还可以让我们使用IP源路由选项。
Traceroute程序的操作过程是,它发送一份TTL字段为1的IP数据报给目的主机。处理这份数据报的第一个路由器将TTL值减1,丢弃改数据报,并发回一份超时ICMP报文。这样就得到了该路径的第一个路由器地址。然后Traceroute程序发送一份TTL为2的数据报,这样我们就可以得到第二个路由器的地址。继续这个过程直至该数据报到达目的主机。
Traceroute程序发送一份UDP数据报给目的主机,但它选择一个不可能的值作为UDP端口号,将使目的主机的UDP模块产生一份"端口不可达"错误的ICMP报文,这样就可以区分接收到的ICMP报文是超时还是端口不可达,以判断什么时候结束。
UDP
UDP是一个简单的面向数据报的传输层协议。应用程序必须关心IP数据报的长度,如果它超过了MTU,就要对IP数据报进行分片。
UDP首部
UDP首部的各字段如下图:
端口号表示发送进程和接收进程,TCP端口号由TCP来查看,而UDP端口号由UDP来查看,TCP端口号和UDP端口号是相互独立的。
IP数据报的最大长度时65535字节,这是由IP首部16比特总长度字段所限制的。除去20字节的IP首部和8字节的UDP首部,UDP数据报中用户数据的最长长度为65507字节。
IP分片
IP把MTU与数据报长度进行比较,如果需要则进行分片。分片可以发生在原始发送端主机上,也可以发生在中间路由器上。把一份IP数据报分片以后,只有到达目的地才进行重新组装。重新组装由目的端的IP层来完成,其目的是使分片和重新组装过程对传输层透明。
IP数据报中的标识字段包含一个唯一值,该值在数据报分片时被复制到每个片中。标志字段用其中一个比特来表示"更多的片",除最后一片外,其它每个组成数据报的片都要报该比特置1。片偏移字段指的是该片偏移原始数据报开始处的位置。
由于IP层本身没有超时重传的机制,即使只丢失一片数据也要重传整个数据报。如果对数据报分片的是中间路由器,而不是起始端系统,那么起始端系统就无法知道数据报是如何被分片的。所以要避免分片。
需要注意的是,任何传输层首部只出现在第1片数据中。
TCP
TCP提供一种面向连接的、可靠的字节流服务。TCP通过以下方式来提供可靠性:
-
应用数据被分割成TCP认为最合适发送的数据块。
-
TCP发送一个段后,它启动一个定时器,如果不能及时收到一个确认,将重发这个报文段。
-
TCP收到发自TCP连接另一端的数据时,将发送一个确认。
-
TCP将保持它首部和数据的校验和。
-
TCP对收到的数据进行重新排序,将收到的数据以正确的顺序交给应用层。
-
TCP的接收端会丢弃重复的数据。
-
TCP还能提供流量控制。
TCP首部
TCP首部的数据格式如下图:
序号用来标识从TCP发送端想TCP接收端发送的数据字节流,它表示在这个报文段中的第一个数据字节,TCP用需要对每个字节进行计数。确认序号包含发送确认的一端所期望收到的下一个序号,确认序号是上次已成功收到的数据字节序号加1。
TCP的流量控制由连接的每一端通过声明的窗口大小来提供,这个值是接收端正期望接收的字节。窗口大小是一个16位的字段,所以窗口大小最大是65535字节,新的窗口扩大选项允许这个值按比例变化以提供更大的窗口。
流量控制
TCP使用滑动窗口协议的形式进行流量控制。该协议允许发送方在停止并等待确认前可以连续发送多个分组,可以加速数据的传输。
使用TCP的滑动窗口协议时,接收方不必确认每一个收到的分组,ACK是累积的,它们表示接收方已经正确收到了一直到确认序号减1的所有字节。
在应用程序读取了TCP缓冲区的数据后,TCP在需要的时候会发送一个ACK,它并不确认任何新数据,只是用来增加窗口的右边沿,因此被称为窗口更新。
滑动窗口的动态性总结如下:
-
发送方不必范松一个全窗口大小的数据。
-
来自接收方的一个报文段确认数据并把窗口向右边滑动。
-
窗口的大小可以减小,但是窗口的右边沿却不能想做移动。
-
接收方在发送一个ACK前不必等待窗口被填满。
TCP需要支持一种被称为慢启动的算法,该算法通过观察到新分组进入网络的速率应该与另一端返回确认的速率相同而进行工作。慢启动为发送方的TCP增加了另一个窗口:拥塞窗口,拥塞窗口被初始化为1个报文段,每收到一个ACK,拥塞窗口就增加一个报文段。发送方取拥塞窗口与通告窗口中的最小值作为发送上限。拥塞窗口是发送方使用的流量控制,而通告窗口则是接收方使用的流量控制。
超时与重传
对每个连接,TCP管理4个不同的定时器:
-
重传定时器用于当希望收到另一端的确认。
-
坚持定时器使窗口大小信息保持不断流动。
-
保活定时器可以检测到一个空闲连接的另一端何时崩溃或重启。
-
2MSL定时器测量一个连接处于TIME_WAIT状态的时间。
TCP在对端ACK超时后按照一定的时间间隔进行重试,在多次重试仍超时后最终会放弃并发送一个复位信号。每次重试的时间间隔是一种被称为指数退避的倍乘关系,直至一个最大值,如重传间隔每次重传时增加1倍直至64秒。
TCP超时与重传中最重要的部分就是对一个给定连接的往返时间(RRT)的测量。由于路由器和网络流量均会变化,因此我们认为这个时间可能经常会发生变化,TCP应该跟踪这些变化并相应地改变其超时时间。
TCP在收到一个失序的报文段时,立即需要产生一个ACK,这个重复的ACK目的在于让对方知道收到一个失序的报文段。发送端端不知道的ACK是由一个丢失的报文段引起的,还是由于仅仅出现了几个报文段的重新排序,如果一连串收到3个或3个以上重复ACK,就非常可能是一个报文段丢失了,于是发送端就重传丢失的数据报文段,而无需等待超时定时器溢出,这就是快速重传算法。
《TCP/IP详解》