详解网络体系结构中的传输层(包含TCP的“三报文握手”和“四报文挥手”)

5.1传输层概述

计算机网络体系结构中的物理层、数据链路层以及网络层它们共同解决了将主机通过异构网络互联起来所面临的问题,实现了主机到主机的通信

但实际上在计算机网络中进行**通信的真正实体是位于通信两端主机中的进程**。

通信的真正端点并不是主机而是主机中的进程。也就是说,端到端的通信是应用进程之间的通信。

过程:
倘若不同主机的不同应用进程要进行网络通信,在应用层需要用不同的端口号代表不同的应用进程。然后通过网络层及其下层来传输应用层报文。接收方的运输层通过不同的端口将收到的应用层报文交付给应用层中响应的应用进程。

根据应用需求的不同,传输层为应用层提供了两种不同的传输协议,即面向连接的TCP和无连接的UDP

在TCP/IP体系中,两个对等传输实体在通信时传送的数据单位,根据所使用的协议是TCP或UDP,分别称之为TCP报文段或UDP用户数据报

5.2传输层端口号、复用和分用的概念

5.2.1端口号

端口号:区分应用层的不同应用进程。

  • 端口号使用16比特表示,取值范围为0~65535;
    • 熟知端口号:0~1023,这些端口号指派给了TCP/IP体系中作重要的一些应用协议,例如:FTP:21/20,HTTP:80,DNS:53。
    • 登记端口号:1024~49151,为没有熟知端口号的应用进程使用。
    • 短暂端口号:49152~65535,为客户进程选择暂时使用。当服务器进程收到客户进程的报文时,就知道了客户进程所使用的动态端口号。通信结束后,这个端口号可供其它客户进程以后使用。
  • 端口号只具有本地意义,极端口号只是为了表示本计算机应用层中的不同进程,不同计算计算机中的相同端口号是没有联系的。
5.2.2发送方的复用和接收方的分用

发送方的不同应用进程发送的应用报文,在传输层使用UDP协议进行封装这称为UDP复用,在传输层使用的TCP协议进行封装,这成为TCP复用。传输层使用端口号来区分不同的应用进程。不管是使用传输层的UDP协议封装成的UDP用户数据包,还是使用传输层的TCP协议封装成的TCP报文段在网络层都需要使用IP协议封装成IP数据报,这称为IP复用。IP数据报首部中协议字段的值用来表明IP数据报的数据载荷部分封装的是何种协议数据单元。取值为6表示封装的是TCP报文段;取值为17表示封装的是UDP用户数据报。

接收方的网络层收到IP数据报后进行IP分用。若IP数据报首部中协议字段的值为6,则把IP数据报的数据载荷部分所封装的TCP报文段上交传输层的TCP;若IP数据报首部中协议字段的值为17,则把IP数据报的数据载荷部分所封装的UDP用户数据报上交传输层的UDP。传输层对TCP报文段进行TCP分用,对UDP用户数据包进行UDP分用,也就是根据端口号,将它们交付给上层相应的应用进程。

5.3TCP和UDP的对比

TCP:

  • 面向连接。应用进程在使用TCP协议之前,必须要建立TCP连接。在传送数据完毕之后,必须要释放已经建立的TCP连接。
  • 可靠传输,使用流量控制和拥塞控制。通过TCP连接传送的数据,无差错、不丢失、不重复,并且按序到达。
  • 仅支持一对一通信。
  • 提供全双工通信。TCP允许通信双方的应用进程在任何时候都能发送和接收数据。TCP连接的两端都设有发送缓存和接收缓存,用来临时存放双向通信的数据。在发送时,应用进程在把数据传送给TCP的缓存后,就可以做自己的事,而TCP在合适的时候把数据发送出去。在接收时,TCP把收到的数据放入缓存,上层的应用进程在合适的时候读取缓存中的数据。
  • 面向字节流。TCP中的“流”指的是流入到进程或从进程流出的字节序列。“面向字节流”的含义是:虽然应用进程和TCP的交互是一次一个数据块(大小不等),但TCP把应用进程交下来的数据仅仅看成是一连串的无结构的字节流。TCP并不知道所传送的字节流的含义。TCP不保证接收方应用进程所收到的数据块和发送方应用进程所发出的数据块具有对应大小的关系,但接收方应用进程收到的字节流必须和发送方应用进程的字节流完全一样。
  • 首部最小是20字节,最大是60字节。

UDP:

  • 无连接。发送数据之前不需要建立连接,发送数据结束之后也不需要建立连接,因此减少了开销和发送数据之前的时延。
  • 不可靠。UDP 尽最大努力交付,即不保证可靠交付,因此主机不需要维持复杂的连接状态表(这里面有许多参数)。没有拥塞控制,因此网络出现的拥塞不会使源主机的发送速率降低。
  • UDP 支持一对一、一对多、多对一和多对多的交互通信。
  • UDP 是面向报文的。UDP 对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界。UDP 一次交付一个完整的报文。
  • UDP 的首部开销小,仅8 个字节。

UDP 没有拥塞控制,因此网络出现的拥塞不会使源主机的发送速率降低。这对某些实时应用是很重要的。很多的实时应用(如IP电话、实时视频会议等)要求源主机以恒定的速率发送数据,并且允许在网络发生拥塞时丢失一些数据,但却不允许数据有太大的时延。
当很多源主机同时都向网络发送高速率的实时视频流的时候,网络就有可能发生拥塞,结果大家都无法正常接收。在这种情况下,应用进程本身可以在不影响应用的实时性的前提下,增加一些提高可靠性的措施,如采用前向纠错重传已丢失的报文

5.4TCP的流量控制

一般来说,我们总是希望数据传输的更快一些。但是如果发送方把数据发送的过快,接收方就有可能来不及接收,这就会造成数据的丢失。
所谓流量控制就是让发送的的发送速率不要太快,要让接收方来得及接收。利用滑动窗口机制可以很方便地在TCP连接上实现对发送方的流量控制。

可以考虑一种情况。接收方向发送方发送了零窗口的报文段后不久,接收端的接收缓存又有了一些接收空间。于是接收端向发送端发送了接收窗口rwnd=**的报文段。然而这个报文段在传送过程中丢失了。发送方一直等待发送方的非零窗口通知,而接收方也一直在等待发送方发送的数据。如果没有其他措施,这种相互等待的死锁局面将一直持续下去。

为了解决这个问题,TCP为每一个连接设有一个持续计时器。只要TCP发送方收到接收方的零窗口通知,就启动持续计时器。若持续计时器设置的时间到期,就发送一个零窗口探测报文段(仅携带一字节的数据),而对方就在确认这个探测报文段时给出了现在的窗口值,如果窗口仍然是,那么收到这个报文段的一方就重新设置持续计时器。如果窗口不是0,那么死锁的僵局就可以打破了。

5.4.1如何控制?

接收方每次收到数据包,可以在发送确定报文的时候,同时告诉发送方自己的缓存区还剩余多少是空闲的,我们也把缓存区的剩余大小称之为接收窗口大小,用变量win来表示接收窗口的大小。
发送方收到之后,便会调整自己的发送速率,也就是调整自己发送窗口的大小,当发送方收到接收窗口的大小为0时,发送方就会停止发送数据,防止出现大量丢包情况的发生。

5.4.2一些术语及其注意点说明

1、由于TCP/IP支持全双工传输,因此通信的双方都拥有两个滑动窗口,一个用于接受数据,称之为接收窗口;一个用于发送数据,称之为拥塞窗口(即发送窗口)。指出接受窗口大小的通知我们称之为窗口通告。
2、接收窗口的大小固定吗?
在早期的TCP协议中,接受接受窗口的大小确实是固定的,不过随着网络的快速发展,固定大小的窗口太不灵活了,成为TCP性能瓶颈之一,也就是说,在现在的TCP协议中,接受窗口的大小是根据某种算法动态调整的。
3、接受窗口越大越好吗?
接受窗口如果太小的话,显然这是不行的,这会严重浪费链路利用率,增加丢包率。那是否越大越好呢?答否,当接收窗口达到某个值的时候,再增大的话也不怎么会减少丢包率的了,而且还会更加消耗内存。所以接收窗口的大小必须根据网络环境以及发送发的的拥塞窗口来动态调整。
4、发送窗口和接受窗口相等吗?
接收方在发送确认报文的时候,会告诉发送发自己的接收窗口大小,而发送方的发送窗口会据此来设置自己的发送窗口,但这并不意味着他们就会相等。首先接收方把确认报文发出去的那一刻,就已经在一边处理堆在自己缓存区的数据了,所以一般情况下接收窗口 >= 发送窗口。

5.5TCP的拥塞控制

拥塞控制是防止发送方发送速率太快,网络来不及处理,从而导致网络拥塞。
在这里插入图片描述
慢开始:是指一开始向网络注入的报文段少,并不是指拥塞窗口cwnd增长速度慢。
拥塞避免:并非指完全能够避免拥塞,而是指在拥塞避免阶段将拥塞窗口控制为按线性规律增长,使网络比较不容易出现拥塞。
在这里插入图片描述

有时,个别报文段会在网络中丢失,但实际上网络并未发生拥塞。这将导致发送方超时重传,并误认为网络发生了拥塞;发送方把拥塞窗口cwnd又设置为最小值1,并错误的启动慢开始算法,因而降低了传输效率。

快重传:就是使发送方尽快重传,而不是等待超时重传计时器超时再重传。

  • 要求接收方不要等待自己发送数据时才进行捎带确认,而是要立即发送确认。
  • 即使受到收到了失序的报文段也要立即发出对已收到的报文段的重复确认。
  • 发送方一旦收到3个连续的重复确认,就将相应的报文段立即重传,而不是等待报文段的超时重传计时器超时再重传。
  • 对于个别丢失的报文段,发送方不会出现超时重传,也就不会误认为出现了拥塞(进而降低拥塞窗口cwnd为1)。使用快重传可以将整个网络的吞吐量提高20%。

在这里插入图片描述

快恢复:发送方一旦收到3个重复确认,就知道现在只是丢失了个别的报文段。于是不启动慢开始算法,而执行快恢复算法。

  • 发送方将慢开始门限值和拥塞窗口值调整为当前窗口的一半;开始执行拥塞避免算法。
  • 也有的快恢复开始当时的拥塞窗口值再增大一些,即等于新的慢开始门限值+3。理由如下:
    • 既然发送方收到3个重复的确认,就表明有3个数据报文段已经离开了网络;
    • 这3个报文段不再消耗网络资源而是停留在接收方的接收缓存中;
    • 可见现在网络中不是堆积了报文段而是减少了3个报文段。因此可以将拥塞窗口适当地扩大一些。

整体过程:
TCP发送方一开始使用慢开始算法,让拥塞窗口值从1开始按照指数规律增大,当增大到慢开始门限初始值时停止使用慢开始算法,转而执行拥塞避免算法,让拥塞窗口按线性加1的规律增大。当发生超时重传时就判断网络可能出现了拥塞,采取相应的措施,一方面将慢开始门限值更新为发生拥塞时拥塞窗口值的一半;另一方面将拥塞窗口值减少为1,并重新开始执行慢开始算法。拥塞窗口值又从1开始按指数规律增大。当增大到了新的慢开始门限值时,停止使用慢开始算法转而执行拥塞避免算法,让拥塞窗口值按线性加1的规律增大。发送方一旦收到3个重复确认,就执行快重传和快恢复。也就是更新慢开始门限值为当前拥塞窗口值的一半,并将拥塞窗口值也取为新的慢开始门限值,转而执行拥塞避免算法,让拥塞窗口值按线性加1的规律增大。

在这里插入图片描述

5.6TCP超时重传时间的选择

如果超时重传时间RTO比往返时间RTT短,这会导致报文的不必要重传,使网络负荷增大。
如果超时重传时间RTO比往返时间RTT长的多,这会使重传推迟的时间变长,使网络的空闲时间增大,降低传输效率。
综上可知,超时重传时间RTO的值应该设置为略大于报文段往返时间RTT的值。然而TCP下层是复杂的互联网环境,网络也分为高低速率,每个IP数据报的转发路由还可能不同。其实超时重传时间的选择并不是这么的简单。

我们不能直接使用某次测量得到的RTT样本来计算超时重传时间RTO,但是可以利用每次测量得到的RTT样本,计算加权平均往返时间RTTs。(这样就可以得到平滑的往返时间)

显然,超时重传时间RTO应略大于加权平均往返时间RTTs

5.7TCP可靠传输的实现

TCP基于以字节为单位的滑动窗口来实现可靠传输。

过程: 窗口是缓存的一部分,用来暂时存放字节流。发送方和接收方各有一个窗口,接收方通过 TCP
报文段中的窗口字段告诉发送方自己的窗口大小,发送方根据这个值和其它信息设置自己的窗口大小。

发送窗口内的字节都允许被发送,接收窗口内的字节都允许被接收。如果发送窗口左部的字节已经发送并且收到了确认,那么就将发送窗口向右滑动一定距离,直到左部第一个字节不是已发送并且已确认的状态;接收窗口的滑动类似,接收窗口左部字节已经发送确认并交付主机,就向右滑动接收窗口。

接收窗口只会对窗口内最后一个按序到达的字节进行确认,例如接收窗口已经收到的字节为 {31, 34, 35},其中 {31} 按序到达,而
{34, 35} 就不是,因此只对字节 31 进行确认。发送方得到一个字节的确认之后,就知道这个字节之前的所有字节都已经被接收。

  1. 虽然发送方的发送窗口是根据接收方的接收窗口设置的,但在同一时刻,发送方的发送窗口并不总是和接收方的接收窗口一样大。
    • 网络传送窗口值需要经历一定时间的滞后,并且这个时间还是不确定的。
    • 发送方还可能根据网络当前的拥塞状况适当的减少自己的发送窗口的尺寸。
  2. 对于不按序到达的数据的处理,TCP无明确规定。
    • 如果接收方把不按序到达的数据一律丢弃,那么接收窗口的管理会比较简单,但这样做对网络资源的利用不利,因为发送方会重复传送较多的数据。
    • TCP通常对不按序到达的数据先是暂时存放在接收窗口中,等到字节流中所缺少的字节收到后,再按序交付上层的应用进程。
  3. TCP要求接收方必须有累计确认和捎带确认机制,这样可以减少传输开销。接收方可以在合适的时候发送确认,也可以在自己有数据要发送时吧确认信息顺便捎带上。
    • 接收方不应过分推迟发送确认,否则会导致发送方不必要的超时重传,这反而浪费了网络的资源。
    • 稍待确认实际上并不经常发生,因为大多数应用程序很少同时在两个方向上发送数据。
  4. TCP的通信是全双工通信。通信中的每一方都在发送和接收报文段。因此,每一方都有自己的发送窗口和接收窗口。

5.8TCP的运输连接管理

TCP运输连接管理有以下三个阶段:
1.通过三报文握手建立TCP连接;
2.基于已建立的TCP连接进行可靠的数据传输;
3.通过四报文挥手释放TCP连接。

5.8.1TCP的连接建立

在这里插入图片描述

过程:存在两台基于TCP进行通信的主机。其中一台主机的某个应用进程主动发起TCP连接建立,称为TCP客户;另一台主机中被动等待TCP建立连接的应用进程,称为TCP服务器。我们可以将TCP建立连接的过程比喻为“握手”,“握手”需要在TCP客户和TCP服务器之间交换3个TCP报文段。
最初,两端的TCP进程都处于关闭状态。一开始,TCP服务器进程首先创建传输控制块,用来存储TCP连接中的一些重要信息,之后,就准备接收TCP客户进程的连接请求。此时,TCP服务器进程就进入监听状态,等待TCP客户进程的连接请求。TCP服务器进程被动等待TCP客户进程的连接请求,也称之为被动打开连接。TCP客户进程也是首先创建传输控制块,然后在打算建立TCP连接时向TCP服务器进程发送TCP连接请求报文段,并进入同步已发送状态。TCP连接请求报文段首部中的同步位SYN被设置为1,表明这是一个TCP连接请求报文段。序号字段seq被设置了一个初始值x作为TCP客户进程所选择的初始序号。要注意:TCP规定SYN被设置为1的报文段不能携带数据,但要消耗掉一个序号。由于TCP连接建立是由TCP客户主动发起的,因此称为主动打开连接。TCP服务进程收到TCP连接请求报文段后如果同意建立连接,则向TCP客户进程发送TCP连接请求确认报文段,并进入同步已接受状态。该同步首部中的同步位SYN和确认位ACK都设置为1,表明这是一个TCP连接请求确认报文段。序号字段seq被设置为了一个初始值y作为TCP服务器进程所选择的初始序号。确认序号ACK的值被设置成了x+1,这是对TCP客户进程所选择的初始序号的确认。要注意:这个报文段也不能携带数据,因为它是SYN被设置为1的报文段,但同样要消耗到1个序号。TCP客户进程收到TCP连接请求确认报文段后,还要向TCP服务器进程发送一个普通的TCP确认报文段,并进入连接已建立状态。该报文段首部中的确认位ACK被设置为1,表明这是一个普通的TCP确认报文段。序号字段seq被设置为x+1,这是因为TCP客户进程发送的第一个TCP报文段的序号为x,并且不携带数据,因此第二个报文段的序号为x+1。要注意:TCP规定普通的TCP确认报文段可以携带数据,但如果不携带数据,则不消耗序号。在这何种情况下所发送的下一个数据报文段的序号仍是x+1。确认号字段ACK被设置为y+1,这是对TCP服务器进程所选择的初始序号的确认。TCP服务器进程收到该确认报文后也进入建立已连接状态。现在TCP双方都进入了连接已建立状态,现在就可以基于TCP连接进行可靠的数据传输了。

问题:为什么TCP客户进程最后还要发送一个普通的TCP确认报文段呢?也就是为什么需要“三报文握手”而不是“两报文握手”?
在这里插入图片描述
TCP客户进程发起一个TCP连接请求报文段。但该报文段在某些网络节点长时间滞留了。这必然会造成该报文段的超时重传,假设重传的报文段被TCP服务器进程正常接收。TCP服务器进程向TCP客户进程发送一个TCP连接请求确认报文段,并进入连接已建立状态。请注意,由于我们改为“两报文握手”,因此TCP服务器进程发送完TCP连接请求确认报文段后,进入的是连接已建立状态,而不像“三报文握手”那样进入同步已接收状态,并等待TCP客户进程发来针对TCP连接请求确认报文段的普通确认报文段。TCP客户进程收到TCP连接请求确认报文段后,进入TCP连接已建立状态。但不会给TCP服务器进程发送针对该报文段的普通确认报文段。现在,TCP双方都处于连接已建立状态。它们可以相互传输数据。之后可以通过“四报文挥手”来释放连接。TCP双方都进入了连接已关闭状态。一段时间后,之前滞留在网络中的那个失效的TCP连接请求报文段到达了TCP服务器进程,TCP服务器进程会误认为这是TCP客户进程,又发起了一个新的TCP连接请求。于是给TCP客户进程发送TCP连接请求确认报文段,并进入连接已建立状态。该报文段到达TCP客户进程,由于TCP客户进程并没有发起新的TCP连接请求,并且处于关闭状态,因此不会理会该报文段。但TCP服务器进程已经进入了连接已建立状态,它认为新的TCP连接已经建立好了,并一直等待TCP客户进程发来数据,这将白白浪费TCP服务器进程所在主机的很多资源。
综上,使用“三报文握手”而不是“两报文握手”是为了防止已经失效的TCP连接请求报文段突然又传送到了TCP服务器进程,因而导致错误

5.8.2TCP的连接释放

在这里插入图片描述

过程:使用TCP客户进程的应用进程通知其主动关闭TCP连接,TCP客户进程会发送TCP连接释放报文段,并进入终止等待1状态。该报文首部中的终止位FIN和确认位ACK的值都被设置为1,表明这是一个TCP连接释放报文段,同时也对之前收到的报文段进行确认。序号seq的值设置为u,它等于TCP客户进程之前已传送过的数据的最后一个字节的序号加1,。要注意:TCP规定终止位FIN等于1的报文段即使不携带数据,也要消耗掉一个序号。确认号ACK字段的值设置为v,它等于TCP客户进程之前收到的数据的最后一个字节的序号加1。TCP服务器进程收到TCP连接释放报文段后,会发送一个普通的TCP确认报文段并进入关闭等待状态。该报文段首部中的确认位ACK的值被设置为1,表明这是一个普通的TCP确认报文段。序号seq字段的值设置为v,它等于TCP服务器进程之前已传送的数据的最后一个字节的序号加1。这也与之前收到的TCP连接释放报文段中的确认号匹配。确认号ACK字段的值设置为u+1,这是对TCP连接释放报文段的确认。TCP服务器进程这时应通知高层应用进程:TCP客户进程要断开与自己的TCP连接。此时,从TCP客户进程到TCP服务器进程这个方向的连接就释放了。这时的TCP连接属于半关闭状态,也就是TCP客户进程已经没有数据要发送了,但TCP服务器进程如果还有数据要发送,TCP客户进程仍要接收。也就是说,从TCP服务器进程到TCP客户进程这个方向的连接还未关闭,这个状态可能会持续一段时间。TCP客户进程收到TCP确认报文段后就进入终止等待2状态。等待TCP服务器进程发出的TCP连接释放报文段。若使用TCP服务器进程的应用进程已经没有数据要发送了,应用进程通知其TCP服务器进程释放连接。由于TCP连接释放是由TCP客户进程主动发起的,因此TCP服务器进程对TCP连接的释放称为被动释放连接。TCP服务器进程发送TCP连接释放报文段并进入最后确认状态。该报文段首部中的确认位FIN和确认位ACK的值都被设置为1,表明这是一个TCP连接释放报文段,同时也对之前后到的报文段进行确认。现在假定序号seq字段的值为w,这是因为在半关闭状态下,TCP服务器进程可能又发送了一些数据。确认号ACK字段的值为u+1,这是对之前收到的TCP连接释放报文段的重复确认。TCP客户进程收到TCP连接释放报文段后,必须针对该报文段发送普通的TCP确认报文段,之后进入时间等待状态。该报文段首部中的确认位ACK的值被设置为1,表明这是一个普通的TCP确认报文段。序号seq字段的值设置为u+1,这是因为TCP客户进程之前发送的TCP连接释放报文段虽然不携带数据,但要消耗掉一个序号。确认号ACK字段的值设置为w+1,这是对TCP连接释放报文段的确认。TCP服务器进程收到该报文段后就进入关闭状态。而TCP客户进程还要经过2MSL后才能进入关闭状态。MSL的意思是最长报文段寿命,有文档建议为2min,也就是说TCP客户进程进入时间等待状态后还要经过4min才能能进入关闭状态。这完全是从工程上来考虑的。对于目前网络来说,这个MSL值可能太长了因此TCP可以允许不同的实现可根据具体情况使用更小的MSL值。

问题:那么,TCP客户进程在发送完最后一个确认报文段后,为什么不直接进入关闭状态,而是要进入时间等待状态,2MSL后才进入关闭状态,这是否有必要呢?
TCP服务器进程发送TCP连接释放报文段后进入最后确认状态。TCP客户进程在收到该报文段后,发送普通的TCP确认报文段,并进入关闭状态而不是时间等待状态。然而,该TCP确认报文段丢失了,这必然会造成TCP服务器进程对之前所发送的TCP连接释放报文段的超时重传,并仍处于最后确认状态。重传的TCP连接释放报文段到达TCP客户进程,由于TCP客户进程处于关闭状态,因此不理睬该报文段,这必然会造成TCP服务器进程反复重传TCP连接释放报文段,并一直处于最后确认状态而无法进入关闭状态。因此,时间等待状态以及处于该状态2MSL时长,可以确保TCP服务器进程可以收到最后一个TCP确认报文段而进入关闭状态。另外TCP客户进程在发送完最后一个TCP确认报文段后,再经过2MSL时长,就可以使本次连接持续时间内所产生的所有报文段都从网络中消失,这样就可以使下一个的TCP连接中不会出现旧连接中的报文段。

TCP中保活计时器的作用
在这里插入图片描述
TCP双方已经建立了连接,后来,TCO=P客户进程所在的主机突然出现了故障。显然,TCP服务器进程以后就不能再收到TCP客户进程发来的数据。因此应当有措施使TCP服务器进程不要再白白等待下去。换句话说,TCP服务器进程应该如何发现这种情况呢?方法就是使用保活计时器。
TCP服务器进程每收到一次TCP客户进程的数据,就重新设置并启动保活计时器(2小时定时)。若保活计时器定时周期内未收到TCP客户进程发来的数据,则当保活计时器到时后,TCP服务器进程就向TCP客户进程发送一个探测报文段,以后则每隔75秒钟发送一次。若一连发出10个探测报文段后仍无TCP客户进程的响应,TCP服务器进程就认为TCP客户进程所在主机出现了故障,接着就关闭这个连接。

问题:四次挥手的原因
客户端发送了 FIN 连接释放报文之后,服务器收到了这个报文,就进入了 CLOSE-WAIT 状态。这个状态是为了让服务器端发送还未传送完毕的数据,传送完毕之后,服务器会发送 FIN 连接释放报文。

TIME_WAIT
客户端接收到服务器端的 FIN 报文后进入此状态,此时并不是直接进入 CLOSED 状态,还需要等待一个时间计时器设置的时间 2MSL。这么做有两个理由:

  • 确保最后一个确认报文能够到达。如果 B 没收到 A 发送来的确认报文,那么就会重新发送连接释放请求报文,A 等待一段时间就是为了处理这种情况的发生。
  • 等待一段时间是为了让本连接持续时间内所产生的所有报文都从网络中消失,使得下一个新的连接不会出现旧的连接请求报文。

5.9TCP报文段的首部格式

在这里插入图片描述
为了实现可靠传输,TCP采用了面向字节流的方式
但在TCP发送数据时,是从发送缓存中取出一部分或全部字节并给其添加一个首部使之成为TCP报文段后进行发送。
一个TCP报文段由首部和数据载荷两部分构成;TCP的全部功能能体现在它首部中个字段的作用。
源端口:占16比特,写入源端口号,用来标识发送该TCP报文段的应用进程。
目的端口:占16比特,写入目的端口号,用来标识接受该TCP报文段的应用进程。
序号:占32比特,序号增加到最后一个后,下一个序号又回到0。指出本TCP报文段数据载荷的第一个字节的序号。
确认号:占32比特,序号增加到最后一个后,下一个序号又回到0。指出期待收到对方下一个TCP报文段的数据载荷的第一个字节的序号,同时也是对之前收到的所有数据的确认。
确认标志位ACK:取值为1时,确认号字段才有效;取值为0时,确认号字段无效。TCP规定,在连接建立后所有TCP报文段都必须把ACK置为1。
同步标志位SYN:在TCP建立连接时用来同步序号。
终止标志位FIN:用来释放TCP连接。

复位标志位RST:用来复位TCP连接。当RST=1时,表明TCP连接出现了异常,必须释放连接,然后再重新建立连接。这样还可以用来拒绝一个非法的报文段或拒绝打开一个TCP连接。
推送标志位PSH:接收方的TCP收到该标志为1的报文段会尽快上交应用进程,而不必等待接收缓存都填满后再向上交付。
首部字段中的紧急标志位URG和紧急指针字段用来实现紧急操作。
紧急标志位URG:紧急标志位取值为1时,紧急指针字段有效,紧急标志位取值为0时,紧急指针字段无效。
紧急指针:占16比特,以字节为单位,用来指明紧急数据的长度。当发送方有紧急数据时,可将紧急数据插队到发送缓存的最前面,并立刻封装到一个TCP报文段中进行发送。紧急指针会指出本报文段数据载荷部分包含了多长的紧急数据,紧急数据之后还是普通数据。
选项:可以增加TCP的功能。
填充。
数据偏移:占4比特,并以4字节为单位。用来指出TCP报文段的数据载荷部分的起始处距离TCP报文段的起始处有多远。这个字段实际上是指出了TCP报文段的首部长度。
窗口:占16比特,以字节为单位。指出发送本报文段的一方的接收窗口。窗口值作为接收方让发送方设置其发送窗口的依据。这是以接收方的接受能力来控制发送方的发送能力,称为流量控制。发送窗口的大小取决于从接收窗口和拥塞窗口中取最小者。
校验和:占16比特,检查范围包括TCP报文段的首部和数据载荷部分。用来检查整个TCP报文段在传输过程中是否出现了误码。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值