TCP/IP协议(一)

1、概述

1.1、分层

image

网络协议通常分不同层次进行开发,每一层分别 负责不同的通信功能。一个协议族,比如TCP/IP,是 一组不同层次上的多个协议的组合。TCP/IP通常被认 为是一个四层协议系统,如图1 - 1所示。

每一层负责不同的功能:

1) 链路层,有时也称作数据链路层或网络接口层, 通常包括操作系统中的设备驱动程序和计算机 中对应的网络接口卡。它们一起处理与电缆(或其他任何传输媒介)的物理接口细节。

2) 网络层,有时也称作互联网层,处理分组在网络中的活动,例如分组的选路。在 TCP/IP协议族中,网络层协议包括I P协议(网际协议),ICMP协议(Internet互联网控制报文协议),以及IGMP协议(Internet组管理协议)。

3 ) 运输层,主要为两台主机上的应用程序提供端到端的通信。在TCP/IP协议族中,有两个 互不相同的传输协议:TCP(传输控制协议)和UDP(用户数据报协议)。 TCP为两台主机提供高可靠性的数据通信。它所做的工作包括把应用程序交给它的数据分 成合适的小块交给下面的网络层,确认接收到的分组,设置发送最后确认分组的超时时钟 等。由于运输层提供了高可靠性的端到端的通信,因此应用层可以忽略所有这些细节。 而另一方面,UDP则为应用层提供一种非常简单的服务。它只是把称作数据报的分组 从一台主机发送到另一台主机,但并不保证该数据报能到达另一端。任何必需的可靠 性必须由应用层来提供。 这两种运输层协议分别在不同的应用程序中有不同的用途,这一点将在后面看到。

4 ) 应用层,负责处理特定的应用程序细节。几乎各种不同的TCP/IP实现都会提供下面这些 通用的应用程序:

• Telnet 远程登录。
• FTP 文件传输协议。
• SMTP 简单邮件传送协议。
• SNMP 简单网络管理协议。

分组、分组交换:

分组交换是一种存储转发的交换方式,它将用户的报文划分成一定长度的分组,以分组为存储转发,因此,它比电路交换的利用率高,比报文交换的时延要小,而具有实时通信的能力。分组交换利用统计时分复用原理,将一条数据链路复用成多个逻辑信道,最终构成一条主叫、被叫用户之间的信息传送通路,称之为虚电路(V.C)实现数据的分组传送。

分组交换的本质就是存储转发,它将所接受的分组暂时存储下来,在目的方向路由上排队,当它可以发送信息时,再将信息发送到相应的路由上,完成转发。其存储转发的过程就是分组交换的过程。

扫描二维码关注公众号,回复: 4831603 查看本文章

分组交换的实质就是将要传输的数据按一定长度分成很多组,为了准确的传送到对方,每个组都打上标识,许多不同的数据分组在物理线路上以动态共享和复用方式进行传输,为了能够充分利用资源,当数据分组传送到交换机时,会暂存在交换机的存储器中,然后根据当前线路的忙闲程度,交换机会动态分配合适的物理线路,继续数据分组的传输,直到传送到目的地。到达目地之后的数据分组再重新组合起来,形成一条完整的数据。

1.2互联网的地址

互联网上的每个接口必须有一个唯一的Internet地址(也称作IP地址)。IP地址长32bit。Internet地址并不采用平面形式的地址空间,如1、2、3等。IP地址具有一定的结构,五类不同的互联网地址格式

如图1 - 5所示。

imageimage

需要再次指出的是,多接口主机具有多个I P地址,其中每个接口都对应一个I P地址。

由于互联网上的每个接口必须有一个唯一的IP地址,因此必须要有一个管理机构为接入互联网的网络分配IP地址。这个管理机构就是互联网络信息中心(InternetNetworkInformationCentre),称作InterNIC。InterNIC只分配网络号。主机号的分配由系统管理员来负责。

Internet注册服务(IP地址和DNS域名)过去由NIC来负责,其网络地址是nic.ddn.mil。1993年4月1日,InterNIC成立。现在,NIC只负责处理国防数据网的注册请求,所有其他的Internet用户注册请求均由InterNIC负责处理,其网址是:rs.internic.net。事实上InterNIC由三部分组成:注册服务(rs.internic.net),目录和数据库服务(ds.internic.net),以及信息服务(is.internic.net)

有三类IP地址:单播地址(目的为单个主机)、广播地址(目的端为给定网络上的所有主 机)以及多播地址(目的端为同一组内的所有主机)。

1.3、封装

当应用程序用TCP传送数据时,数据被送入协议栈中,然后逐个通过每一层直到被当作一串比特流送入网络。其中每一层对收到的数据都要增加一些首部信息(有时还要增加尾部信息),

该过程如图1-7所示。TCP传给IP的数据单元称作TCP报文段或简称为TCP段(TCPsegment)。IP传给网络接口层的数据单元称作IP数据报(IPdatagram)。通过以太网传输的比特流称作帧(Frame)。

图1-7中帧头和帧尾下面所标注的数字是典型以太网帧首部的字节长度。在后面的章节中我们将详细讨论这些帧头的具体含义。

以太网数据帧的物理特性是其长度必须在46~1500字节之间。 更准确地说,图1-7中IP和网络接口层之间传送的数据单元应该是分组(packet)。分组既可以是一个IP数据报,也可以是IP数据报的一个片(fragment)

image

许多应用程序都可以使用TCP或UDP来传送数据。运输层协议在生成报文首部时要存入一个应用程序的标识符。TCP和UDP都用一个16bit的端口号来表示不同的应用程序。TCP和UDP把源端口号和目的端口号分别存入报文首部中。

1.4、分用

当目的主机收到一个以太网数据帧时,数据就开始从协议栈中由底向上升,同时去掉各层协议加上的报文首部。每层协议盒都要去检查报文首部中的协议标识,以确定接收数据的上层协议。这个过程称作分用(Demultiplexing),

图1-8显示了该过程是如何发生的。

image

2、链路层

2.1、最大传输单元MTU

任何网络结构对数据帧的长度都有一个限制,如以太网和802. 3其最大值分别是1500和1492字节。链路层的这个特性称作MTU,最大传输单元。不同类型的网络大多数都有一个上限。

如果IP层有一个数据报要传,而且数据的长度比链路层的MTU还大,那么IP层就需要进行分片(fragmentation),把数据报分成若干片,这样每一片都小于MTU。

图2-5列出了一些典型的MTU值,它们摘自RFC1191[MogulandDeering1990]。点到点的链路层(如SLIP和PPP)的MTU并非指的是网络媒体的物理特性。相反,它是一个逻辑限制,目的是为交互使用提供足够快的响应时间。

image

2.2、串行线路吞吐量计算

如果线路速率是9600b/s,而一个字节有8bit,加上一个起始比特和一个停止比特,那么线路的速率就是960B/s(字节/秒)。以这个速率传输一个1024字节的分组需要1066ms。如果用SLIP链接运行一个交互式应用程序,同时还运行另一个应用程序如FTP发送或接收1024字节的数据,那么一般来说就必须等待一半的时间(533ms)才能把交互式应用程序的分组数据发送出去。

必须等待一半时间的原因来自于:CSMA/CD的基本原理是:所有节点都共享网络传输信道,节点在发送数据之前,首先检测信道是否空闲,如果信道空闲则发送,否则就等待;在发送出信息后,再对冲突进行检测,当发现冲突时,则取消发送。

CSMA/CD的基本原理是:每个节点都共享网络传输信道,在每个站要发送数据之前,都会检测信道是否空闲,如果空闲则发送,否则就等待;在发送出信息后,则对冲突进行检测,当发现冲突时,则取消发送。我们可以借助于生活中的一个例子来解释:假设有这一层楼,两旁住了几十户人,中间只有一条仅供一人同行的走道。我们看情况会怎么样:①当这些住户要经过走道出来时,首先探出头来看看走道上有没有人(这就是载波监听),如果没有,就通过走道出来;②如果走道上有人走,那么就一直盯着走道,直到走道上没人时再出来(1-坚持监听算法);③如果有两人同时看到走道上没有人,而同时走向走道(冲突检测),则两个人发现时就马上回到自己屋里。在整个协议中最关键的是载波监听、冲突检测两部分

把SLIP的MTU缩短到256就意味着链路传输一帧最长需要266ms,它的一半是133ms(这是一般需要等待的时间)。这样情况会好一些,但仍然不完美。我们选择它的原因(与64或128相比)是因为大块数据提供良好的线路利用率(如大文件传输)。假设CSLIP的报文首部是5个字节,数据帧总长为261个字节,256个字节的数据使线路的利用率为98.1%,帧头占了1.9%,这样的利用率是很不错的。如果把MTU降到256以下,那么将降低传输大块数据的最大吞吐量。

对以上描述的理解:

1、网络的物理特性完全支持大数据块的传输。

2、但是很多链路层协议仍然会设置最大传输单元,

3、原因是基于CSMA/CD原理数据块越大,其他程序的传输等待就会越久(一般等待最大数据块传输时间的一半时间),而这个等待时间对于交互式应用是不可容忍的。

4、如果把最大传输单元设置过小,传输频率自然上升,碰撞发生越多,线路的利用率就会降低,因为有一部分时间在处理冲突,信道是不传输东西的。

5、综上只能根据网络结构特性选择一个合适的MTU。

6、以上例子平均等待时间的计算(传输最大数据帧所需时间的一半)只适用于SLIP链路,不同网络结构有不同的数值。

3、IP网际协议

3.1、引言

IP是TCP/IP协议族中最为核心的协议。所有的TCP、UDP、ICMP及IGMP数据都以IP数据报格式传输。IP提供不可靠、无连接的数据报传送服务。

不可靠(unreliable)的意思是它不能保证IP数据报能成功地到达目的地。IP仅提供最好的传输服务。如果发生某种错误时,如某个路由器暂时用完了缓冲区,IP有一个简单的错误处理算法:丢弃该数据报,然后发送ICMP消息报给信源端。任何要求的可靠性必须由上层来提供(如TCP)。

无连接(connectionless)这个术语的意思是IP并不维护任何关于后续数据报的状态信息。每个数据报的处理是相互独立的。这也说明,IP数据报可以不按发送顺序接收。如果一信源向相同的信宿发送两个连续的数据报(先是A,然后是B),每个数据报都是独立地进行路由选择,可能选择不同的路线,因此B可能在A到达之前先到达。

3.2、IP首部

IP数据报的格式如图3-1所示。普通的IP首部长为20个字节,除非含有选项字段。

image 

4个字节的32bit值以下面的次序传输:首先是0~7bit,其次8~15bit,然后16~23bit,最后是24~31bit。这种传输次序称作bigendian字节序。由于TCP/IP首部中所有的二进制整数在网络中传输时都要求以这种次序,因此它又称作网络字节序。以其他形式存储二进制整数的机器,如littleendian格式,则必须在传输数据之前把首部转换成网络字节序。

总长度字段是指整个IP数据报的长度,以字节为单位。利用首部长度字段和总长度字段,就可以知道IP数据报中数据内容的起始位置和长度。由于该字段长16比特,所以IP数据报最长可达65535字节(回忆图2-5,超级通道的MTU为65535。它的意思其实不是一个真正的MTU—它使用了最长的IP数据报)。当数据报被分片时,该字段的值也随着变化。

尽管可以传送一个长达65535字节的IP数据报,但是大多数的链路层都会对它进行分片。而且,主机也要求不能接收超过576字节的数据报。由于TCP把用户数据分成若干片,因此一般来说这个限制不会影响TCP。在后面的章节中将遇到大量使用UDP的应用(RIP,TFTP,BOOTP,DNS,以及SNMP),它们都限制用户数据报长度为512字节,小于576字节。但是,事实上现在大多数的实现(特别是那些支持网络文件系统NFS的实现)允许超过8192字节的IP数据报。

3.3、IP选路

image

开始讨论IP选路之前,首先要理解内核是如何维护路由表的。路由表中包含的信息决定了IP层所做的所有决策。
我们列出了IP搜索路由表的几个步骤:
1)搜索匹配的主机地址;
2)搜索匹配的网络地址;
3)搜索默认表项(默认表项一般在路由表中被指定为一个网络表项,其网络号为0)。
匹配主机地址步骤始终发生在匹配网络地址步骤之前。IP层进行的选路实际上是一种选路机制,它搜索路由表并决定向哪个网络接口发送分组。这区别于选路策略,它只是一组决定把哪些路由放入路由表的规则。IP执行选路机制,而路由守护程序则一般提供选路策略

3.3、IP校验和

为了计算一份数据报的IP检验和,首先把检验和字段置为0。然后,对首部中每个16bit进行二进制反码求和(整个首部看成是由一串16bit的字组成),结果存在检验和字段中。当收到一份IP数据报后,同样对首部中每个16bit进行二进制反码的求和。由于接收方在计算过程中包含了发送方存在首部中的检验和,因此,如果首部在传输过程中没有发生任何差错,那么接收方计算的结果应该为全1。如果结果不是全1(即检验和错误),那么IP就丢弃收到的数据报。但是不生成差错报文,由上层去发现丢失的数据报并进行重传。

3.4、IP分片

物理网络层一般要限制每次发送数据帧的最大长度。任何时候IP层接收到一份要发送的IP数据报时,它要判断向本地哪个接口发送数据(选路),并查询该接口获得其MTU。IP把MTU与数据报长度进行比较,如果需要则进行分片。分片可以发生在原始发送端主机上,也可以发生在中间路由器上。

把一份IP数据报分片以后,只有到达目的地才进行重新组装(这里的重新组装与其他网络协议不同,它们要求在下一站就进行进行重新组装,而不是在最终的目的地)。重新组装由目的端的IP层来完成,其目的是使分片和重新组装过程对运输层(TCP和UDP)是透明的,除了某些可能的越级操作外。已经分片过的数据报有可能会再次进行分片(可能不止一次)。IP首部中包含的数据为分片和重新组装提供了足够的信息。

回忆IP首部,下面这些字段用于分片过程。对于发送端发送的每份IP数据报来说,其标识字段都包含一个唯一值。该值在数据报分片时被复制到每个片中(我们现在已经看到这个字段的用途)。标志字段用其中一个比特来表示“更多的片”。除了最后一片外,其他每个组成数据报的片都要把该比特置1。片偏移字段指的是该片偏移原始数据报开始处的位置。另外,当数据报被分片后,每个片的总长度值要改为该片的长度值。

最后,标志字段中有一个比特称作“不分片”位。如果将这一比特置1,IP将不对数据报进行分片。相反把数据报丢弃并发送一个ICMP差错报文

当IP数据报被分片后,每一片都成为一个分组,具有自己的IP首部,并在选择路由时与其他分组独立。这样,当数据报的这些片到达目的端时有可能会失序,但是在IP首部中有足够的信息让接收端能正确组装这些数据报片。

使用UDP很容易导致IP分片(在后面我们将看到,TCP试图避免分片,但对于应用程序来说几乎不可能强迫TCP发送一个需要进行分片的长报文段)

4、UDP用户数据报协议

4.1、引言

DP是一个简单的面向数据报的运输层协议:进程的每个输出操作都正好产生一个UDP数据报,并组装成一份待发送的IP数据报。这与面向流字符的协议不同,如TCP,应用程序产生的全体数据与真正发送的单个IP数据报可能没有什么联系。

应用程序必须关心I P数据报的长度。如果它超过网络的MTU(2. 8节),那么就要对IP数 据报进行分片。

4.2、UDP首部

image

UDP长度字段指的是UDP首部和UDP数据的字节长度。该字段的最小值为8字节(发送一份0字节的UDP数据报是OK)。这个UDP长度是有冗余的。IP数据报长度指的是数据报全长,因此UDP数据报长度是全长减去IP首部的长度(该值在首部长度字段中指定)    。

4.3UDP校验和

UDP检验和覆盖UDP首部和UDP数据。回想IP首部的检验和,它只覆盖IP的首部—并不覆盖IP数据报中的任何数据。

UDP和TCP在首部中都有覆盖它们首部和数据的检验和。UDP的检验和是可选的,而TCP的检验和是必需的。

尽管UDP检验和的基本计算方法与我们在上文中描述的IP首部检验和计算方法相类似(16bit字的二进制反码和),但是它们之间存在不同的地方。首先,UDP数据报的长度可以为奇数字节,但是检验和算法是把若干个16bit字相加。解决方法是必要时在最后增加填充字节0,这只是为了检验和的计算(也就是说,可能增加的填充字节不被传送)。

其次,UDP数据报和TCP段都包含一个12字节长的伪首部,它是为了计算检验和而设置的。伪首部包含IP首部一些字段。其目的是让UDP两次检查数据是否已经正确到达目的地(例如,IP没有接受地址不是本主机的数据报,以及IP没有把应传给另一高层的数据报传给UDP)。UDP数据报中的伪首部格式如图11-3所示。

image

5、TCP链接的建立与终止

5.1、TCP通信过程

在一个TCP连接中,仅有两方进行彼此通信。在第12章介绍的广播和多播不能用于TCP。TCP通过下列方式来提供可靠性:

•应用数据被分割成TCP认为最适合发送的数据块。这和UDP完全不同,应用程序产生的数据报长度将保持不变。由TCP传递给IP的信息单位称为报文段或段(segment)。

•当TCP发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。在第21章我们将了解TCP协议中自适应的超时及重传策略。

•当TCP收到发自TCP连接另一端的数据,它将发送一个确认。这个确认不是立即发送,通常将推迟几分之一秒。

•TCP将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP将丢弃这个报文段和不确认收到此报文段(希望发端超时并重发)。

•既然TCP报文段作为IP数据报来传输,而IP数据报的到达可能会失序,因此TCP报文段的到达也可能会失序。如果必要,TCP将对收到的数据进行重新排序,将收到的数据以正确的顺序交给应用层。

•既然IP数据报会发生重复,TCP的接收端必须丢弃重复的数据。

•TCP还能提供流量控制。TCP连接的每一方都有固定大小的缓冲空间。TCP的接收端只允许另一端发送接收端缓冲区所能接纳的数据。这将防止较快主机致使较慢主机的缓冲区溢出。

5.2、TCP首部

image

1、序号用来标识从TCP发端向TCP收端发送的数据字节流,它表示在这个报文段中的的第一个数据字节。如果将字节流看作在两个应用程序间的单向流动,则TCP用序号对每个字节进行计数。序号是32bit的无符号数,序号到达232-1后又从0开始。

2、当建立一个新的连接时,SYN标志变1。序号字段包含由这个主机选择的该连接的初始序号ISN(InitialSequenceNumber)。该主机要发送数据的第一个字节序号为这个ISN加1,因为SYN标志消耗了一个序号(将在下章详细介绍如何建立和终止连接,届时我们将看到FIN标志也要占用一个序号)。

3、既然每个传输的字节都被计数,确认序号包含发送确认的一端所期望收到的下一个序号。因此,确认序号应当是上次已成功收到数据字节序号加1。只有ACK标志(下面介绍)为1时确认序号字段才有效。

4、TCP为应用层提供全双工服务。这意味数据能在两个方向上独立地进行传输。因此,连接的每一端必须保持每个方向上的传输数据序号。

在TCP首部中有6个标志比特。它们中的多个可同时被设置为1。
URG紧急指针(urgentpointer)有效。
ACK确认序号有效。
PSH接收方应该尽快将这个报文段交给应用层。
RST重建连接。
SYN同步序号用来发起一个连接。
FIN发端完成发送任务。

5.3、连接的建立与终止

为了了解一个TCP连接在建立及终止时发生了什么,我们在系统svr4上键入下列命令:

image

以上是telnet 建立一条链接和断开一条链接的过程;

tcpdump的输出:

image

对于TCP段,每个输出行开始按如下格式显示:源> 目的: 标志

这里的标志代表TCP首部(图1 7 - 2)中6个标志比特中的4个。图1 8 - 2显示了表示标志的5 个字符的含义。

image

在第1行中,字段1415531521:1415531521(0)表示分组的序号是1415531521,而报文段中数据字节数为0。
tcpdump显示这个字段的格式是开始的序号、一个冒号、隐含的结尾序及圆括号内的数据字节数。显示序号和隐含结尾序号的优点是便于了解数据字节数大于0时的隐含结尾序号。
这个字段只有在满足条件:
       (1)报文段中至少包含一个数据字节;
或者(2)SYN、FIN或RST被设置为1时才显示。
图18-1中的第1、2、4和6行是因为标志比特被置为1而显示这个字段的,在这个例子中通信双方没有交换任何数据。
在第2行中,字段ack1415531522表示确认序号。它只有在首部中的ACK标志比特被设置1时才显示。
每行显示的字段win4096表示发端通告的窗口大小。在这些例子中,我们没有交换任何数据,窗口大小就维持默认情况下的4096。
图18-1中的最后一个字段<mss1024>表示由发端指明的最大报文段长度选项。发端将不接收超过这个长度的TCP报文段。这通常是为了避免分段

5.4、建立链接协议

1)请求端(通常称为客户)发送一个SYN段指明客户打算连接的服务器的端口,以及初始序号(ISN,在这个例子中为1415531521)。这个SYN段为报文段1。
2)服务器发回包含服务器的初始序号的SYN报文段(报文段2)作为应答。同时,将确认序号设置为客户的ISN加1以对客户的SYN报文段进行确认。一个SYN将占用一个序号。
3)客户必须将确认序号设置为服务器的ISN加1以对服务器的SYN报文段进行确认(报文段3)。
这三个报文段完成连接的建立。这个过程也称为三次握手(three-wayhandshake)。

image

发送第一个SYN的一端将执行主动打开(activeopen)。接收这个SYN并发回下一个SYN的另一端执行被动打开(passiveopen)

当一端为建立连接而发送它的SYN时,它为连接选择一个初始序号。ISN随时间而变化,因此每个连接都将具有不同的ISN。RFC793[Postel1981c]指出ISN可看作是一个32比特的计数器,每4ms加1。这样选择序号的目的在于防止在网络中被延迟的分组在以后又被传送,而导致某个连接的一方对它作错误的解释。

5.5、连接协议终止

建立一个连接需要三次握手,而终止一个连接要经过4次握手。这由TCP的半关闭(half-close)造成的。

既然一个TCP连接是全双工(即数据在两个方向上能同时传递),因此每个方向必须单独地进行关闭。这原则就是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向连接。当一端收到一个FIN,它必须通知应用层另一端几经终止了那个方向的数据传送。发送FIN通常是应用层进行关闭的结果。

首先进行关闭的一方(即发送第一个F I N)将执行主动关闭,而另一方(收到这个F I N)执行被动关闭。通常一方完成主动关闭而另一方完成被动关闭

image

当服务器收到这个FIN,它发回一个ACK,确认序号为收到的序号加1(报文段5)。和SYN一样,一个FIN将占用一个序号。同时TCP服务器还向应用程序(即丢弃服务器)传送一个文件结束符。接着这个服务器程序就关闭它的连接,导致它的TCP端发送一个FIN(报文段6),客户必须发回一个确认,并将确认序号设置为收到序号加1(报文段7)

图18-4显示了终止一个连接的典型握手顺序。我们省略了序号。在这个图中,发送FIN将导致应用程序关闭它们的连接,这些FIN的ACK是由TCP软件自动产生的。

image

5.6、连接建立超时

有很多情况导致无法建立连接。一种情况是服务器主机没有处于正常状态。为了模拟这种情况,我们断开服务器主机的电缆线,然后向它发出telnet命令。图18-6显示了tcpdump的输出。

image

在这个输出中有趣的一点是客户间隔多长时间发送一个SYN,试图建立连接。第2个SYN与第1个的间隔是5.8秒,而第3个与第2个的间隔是24秒。

这是因为BSD版的TCP软件采用一种500ms的定时器。这种500ms的定时器用于确定本章中所有的各种各样的TCP超时。当我们键入telnet命令,将建立一个6秒的定时器(12个时钟滴答(tick)),但它可能在之后的5.5秒~6秒内的任意时刻超时。图18-7显示了这一发生过程。尽管定时器初始化为12个时钟滴答,但定时计数器会在设置后的第一个0~500ms中的任意时刻减1。从那以后,定时计数器大约每隔500ms减1,但在第1个500ms内是可变的(我们使用限定词“大约”是因为在TCP每隔500ms获得系统控制的瞬间,系统内核可能会优先处理其他中断)。

image

当滴答计数器为0时,6秒的定时器便会超时(见图18-7),这个定时器会在以后的24秒(48个滴答)重新复位。之后的下一个定时器将更接近24秒,因为当TCP的500ms定时器被内核调用时,它就会被修改一次。

5.7、最大报文长度

最大报文段长度(MSS)表示TCP传往另一端的最大块数据的长度。当一个连接建立时,连接的双方都要通告各自的MSS。我们已经见过MSS都是1024。这导致IP数据报通常是40字节长:20字节的TCP首部和20字节的IP首部。

在有些书中,将它看作可“协商”选项。它并不是任何条件下都可协商。当建立一个连接时,每一方都有用于通告它期望接收的MSS选项(MSS选项只能出现在SYN报文段中)。如果一方不接收来自另一方的MSS值,则MSS就定为默认值536字节(这个默认值允许20字节的IP首部和20字节的TCP首部以适合576字节IP数据报)。

只有当一端的主机以小于576字节的MTU直接连接到一个网络中,避免这种分段才会有效。如果两端的主机都连接到以太网上,都采用536的MSS,但中间网络采用296的MTU,也将会出现分段。使用路径上的MTU发现机制关于这个问题的唯一方法。

5.8、TCP的半关闭

image

5.9、TCP两边同时打开

两个应用程序同时彼此执行主动打开的情况是可能的,尽管发生的可能性极小。每一方必须发送一个SYN,且这些SYN必须传递给对方。这需要每一方使用一个对方熟知的端口作为本地端口。这又称为同时打开(simultaneousopen)。例如,主机A中的一个应用程序使用本地端口7777,并与主机B的端口8888执行主动打开。主机B中的应用程序则使用本地端口8888,并与主机A的端口7777执行主动打开。

这与下面的情况不同:主机A中的Telnet客户程序和主机B中Telnet的服务器程序建立连接,与此同时,主机B中的Telnet客户程序与主机A的Telnet服务器程序也建立连接。在这个Telnet例子中,两个Telnet服务器都执行被动打开,而不是主动打开,并且Telnet客户选择的本地端口不是另一端Telnet服务器进程所熟悉的端口。

TCP是特意设计为了可以处理同时打开,对于同时打开它仅建立一条连接而不是两条连接(其他的协议族,最突出的是OSI运输层,在这种情况下将建立两条连接而不是一条连接)。

当出现同时打开的情况时,状态变迁与图18-13所示的不同。两端几乎在同时发送SYN,并进入SYNSENT状态。当每一端收到SYN时,状态变为SYNRCVD(如图18-12),同时它们都再发SYN并对收到的SYN进行确认。当双方都收到SYN及相应的ACK时,状态都变迁为ESTABLISHED。图18-17显示了这些状态变迁过程。

image

一个同时打开的连接需要交换4个报文段,比正常的三次握手多一个。此外,要注意的是我们没有将任何一端称为客户或服务器,因为每一端既是客户又是服务器。

5.10、TCP两边同时关闭

我们在以前讨论过一方(通常但不总是客户方)发送第一个FIN执行主动关闭。双方都执行主动关闭也是可能的,TCP协议也允许这样的同时关闭(simultaneousclose)。

在图18-12中,当应用层发出关闭命令时,两端均从ESTABLISHED变为FIN_WAIT_1。这将导致双方各发送一个FIN,两个FIN经过网络传送后分别到达另一端。收到FIN后,状态由FIN_WAIT_1变迁到CLOSING,并发送最后的ACK。当收到最后的ACK时,状态变化为TIMEWAIT。图18-19总结了这些状态的变化。

image

5.11、TCP状态变迁

imageimage

TCP首部中的RST比特是用于“复位”的。一般说来,无论何时一个报文段发往基准的连接(referencedconnection)出现错误,TCP都会发出一个复位报文段(这里提到的“基准的连接”是指由目的IP地址和目的端口号以及源IP地址和源端口号指明的连接。

6、TCP的成块数据流与超时重传

6.1、Nagle算法

该算法要求一个TCP连接上最多只能有一个未被确认的未完成的小分组,在该分组的确认到达之前不能发送其他的小分组。相反,TCP收集这些少量的分组,并在确认到来时以一个分组的方式发出去。该算法的优越之处在于它是自适应的:确认到达得越快,数据也就发送得越快。而在希望减少微小分组数目的低速广域网上,则会发送更少的分组

Nagle算法描述的分组就是TCP的成块数据。

6.2、窗口的概念

理解:窗口类似发送方或接收方的一块缓存,发送放用来存放需要发送的数据,等待ACK到来时把数据成块的发送出去。接收方用来存放接收到的数据,把接收到的数据进行重新排序。窗口的大小就是这块缓存的大小。

滑动窗口:

image

在这个图中,我们将字节从1至11进行标号。接收方通告的窗口称为提出的窗口(offeredwindow),它覆盖了从第4字节到第9字节的区域,表明接收方已经确认了包括第3字节在内的数据,且通告窗口大小为6。

1)称窗口左边沿向右边沿靠近为窗口合拢。这种现象发生在数据被发送和确认时。
2)当窗口右边沿向右移动时将允许发送更多的数据,我们称之为窗口张开。这种现象发生在另一端的接收进程读取已经确认的数据并释放了TCP的接收缓存时。
3)当右边沿向左移动时,我们称之为窗口收缩。HostRequirementsRFC强烈建议不要使用这种方式。但TCP必须能够在某一端产生这种情况时进行处理。

6.3、慢启动/拥塞避免/快速恢复算法工作过程

需要知道几个定义:

1)拥塞窗口cwnd:TCP发送端创建的一个窗口,当TCP链接建立时,拥塞窗口被初始化为1个报文段(即另一端通告的报文段大小),发送端每次发送拥塞窗口大小的数据。该窗口是发送方的流量控制。

2)慢启动算法:发送方开始发送一个报文段(拥塞窗口初始化的大小),等待接收ACK;第一次可接收一个ACK,每接收一个ACK拥塞窗口大小加一个报文段 即第二次可发送两个报文段;再次等待接收ACK,第二次可接收两个ACK,拥塞窗口变为四个报文段即第三次可发送四个报文段;以此类推,每次发送的报文段为1,2,4,8,16….成指数增长

3)慢启动门限ssthresh:TCP维护的一个变量,以字节为单位,用来标识TCP传输数据的某个介限。拥塞算法里使用的变量。

4)拥塞避免算法:参照慢启动算法理解,发送方每接收一个ACK,cwnd(拥塞窗口)就增加 1/cwnd。与慢启动的指数增加比起来,这是一种加性增长。我们希望在一个往返时间内最多为cwnd增加1个报文段(不管在这个RTT中收到了多少个ACK),然而慢启动将根据这个往返时间中所收到的确认的个数增加cwnd。

5)通告窗口:TCP接收端创建的一个窗口,是描述接收端缓存大小的窗口,每次ACK数据都会包含通告窗口的可用大小数据。该窗口是接收方可用缓存大小。

算法工作过程如下:

拥塞避免算法和慢启动算法需要对每个连接维持两个变量:一个拥塞窗口cwnd和一个慢启动门限ssthresh。这样得到的算法的工作过程如下:

1)对一个给定的连接,初始化cwnd为1个报文段,ssthresh为65535个字节。

2) TCP输出进程的输出不能超过cwnd和接收方通告窗口中较小的一方的大小。

3)TCP以慢启动算法发送数据量指数上涨,当上涨到cwnd>ssthresh时TCP发送数据量以拥塞避免算法加性增长。

4)当数据量上涨到一定程度(最大也不可能超过cwnd或接收方通告窗口大小),拥塞发生时(收到重复确认)ssthresh被设置为当前窗口(cwnd和接收方通告窗口较小的一方)大小的一半,但最小是2个报文段。之后根据第3条可得会继续执行拥塞避免算法。

5)如果是超时引起了拥塞cwnd会设置为1个报文段,根据第3条可得会继续执行慢启动算法。

image

快速重传:TCP接收方在收到一个失序的报文段时,需要立即产生一个ACK(一个重复的ACK)。该重复的ACK目的在于让发送方知道自己收到了一个失序的报文段,并告诉对方自己希望收到的序号。

快速恢复算法:假如这只是一些报文段的重新排序,则在重新排序的报文段被处理并产生一个新的ACK之前,只可能产生1~2个重复的ACK。如果一连串收到3个或3个以上的重复ACK,就非常可能是一个报文段丢失了,于是我们就重传丢失的数据报文段,而无需等待超时定时器溢出。这就 是快速重传算法。

1)当收到第一个ACK开始cwnd保持不变(ACK变计数),当收到第3个重复的ACK时,将ssthresh设置为当前拥塞窗口cwnd的一半。重传丢失的报文段。设置cwnd为ssthresh加上三个报文段大小。

2)之后每次收到一个重复的ACK时,cwnd增加1个报文段大小并发送1个分组(如果新的cwnd允许发送)。

3)当下一个确认新数据的ACK到达时这个ACK应该是在进行重传后的一个往返时间内对步骤1中重传的确认。另外,这个ACK也应该是对丢失的分组和收到的第1个重复的ACK之间的所有中间报文段的确认设置cwnd为ssthresh(在第1步中设置的值,注意整个过程ssthresh只在第一步变化了一次)。并进入正常拥塞避免算法。

image

内容摘自:TCP-IP详解卷1:协议

猜你喜欢

转载自www.cnblogs.com/happydreamzjl/p/10240706.html