前言
本章先概括介绍运输层协议 的特点、进程之间的通信和端口等重要概念,然后讲述比 较简单的UDP协议。其余的篇幅都是讨论较为复杂但非常重要的TCP协议 和可靠传输的工作原理 ,包括停止等待协议和ARQ协议。在详细讲述TCP报文段的首部格式 之后,讨论TCP的三个重要问题:滑动窗口、流量控制和拥塞控制机制 。最后,介绍TCP的连接管理。
运输层是整个网络体系结构中的关键层次之一。一定要弄清以下一些重要概念: (1)运输层为相互通信的应用进程提供逻辑通信。 (2)端口和套接字的意义。 (3)无连接的UDP的特点。 (4)面向连接的TCP的特点。 (5)在不可靠的网络上实现可靠传输的工作原理,停止等待协议和ARQ协议。 (6) TCP的滑动窗口、流量控制、拥塞控制和连接管理。
1. 运输层协议概述
1.1 进程之间的通信
从通信和信息处理的角度看,运输层向它上面的应用层提供通信服务,它属于面向通 信部分的最高层,同时也是用户功能中的最低层。当网络的边缘部分中的两台主机使用网络的核心部分的功能进行端到端的通信时,只有主机的协议栈才有运输层,而网络核心部分中的路由器在转发分组时都只用到下三层的功能。
主机的协议栈指的是网卡功能
下面通过图5-1的示意图来说明运输层的作用。设局域网LANi上的主机A和局域网LAN2上的主机B通过互连的广域网WAN进行通信。我们知道,IP协议能够把源主机A发送出的分组,按照首部中的目的地址,送交到目的主机B,那么,为什么还需要运输层呢?
从IP层来说,通信的两端是两台主机。IP数据报的首部明确地标志了这两台主机的IP地址。但“两台主机之间的通信”这种说法还不够清楚。这是因为,真正进行通信的实体是在主机中的进程,是这台主机中的一个进程和另一台主机中的一个进程在交换数据(即通信)。因此严格地讲,两台主机进行通信就是两台主机中的应用进程互相通信 。
IP协议虽然能把分组送到目的主机,但是这个分组还停留在主机的网络层而没有交付主机中的应用进程。从运输层的角度看,通信的真正端点并不是主机而是主机中的进程。也就是说,端到端的通信是应用进程之间的通信。在一台主机中经常有多个应用进程同时分别和另一台主机中的多个应用进程通信。
图5-1中两个运输层之间有一个双向粗箭头,写明“运输层提供应用进程间的逻辑通信”。“逻辑通信”的意思是:从应用层来看,只要把应用层报文交给下面的运输层,运输层就可以把这报文传送到对方的运输层(哪怕双方相距很远,例如几千公里),好像这种通信就是沿水平方向直接传送数据。但事实上这两个运输层之间并没有一条水平方向的物理连接。数据的传送是沿着图中的虚线方向(经过多个层次)传送的 。“逻辑通信”的意思是“好像是这样通信,但事实上并非真的这样通信”。
从这里可以看出网络层和运输层有明显的区别。网络层为主机之间提供逻辑通信,而 运输层为应用进程之间提供端到端的逻辑通信 (见图5-2)o然而正如后面还要讨论的,运输层还具有网络层无法代替的许多其他重要功能。
运输层向高层用户屏蔽了下面网络核心的细节(如网络拓扑、所采用的路由选择协议等),它使应用进程看见的就是好像在两个运输层实体之间有一条端到端的逻辑通信信道,但这条逻辑通信信道对上层的表现却因运输层使用的不同协议而有很大的差别。当运输层采用面向连接的TCP协议时,尽管下面的网络是不可靠的(只提供尽最大努力服务),但这种逻辑通信信道就相当于一条全双工的可靠信道。但当运输层采用无连接的UDP协议时,这种逻辑通信信道仍然是一条不可靠信道。
1.2 运输层的两个主要协议
TCP/IP运输层的两个主要协议都是互联网的正式标准,即: (1)用户数据报协议 UDP (User Datagram Protocol) [RFC 768] ⑵ 传输控制协议 TCP (Transmission Control Protocol) [RFC 793]
图5-3给出了这两种协议在协议栈中的位置
按照OSI的术语,两个对等运输实体在通信时传送的数据单位叫做运输协议数据单元TPDU (Transport Protocol Data Unit) o但在TCP/IP体系中,则根据所使用的协议是TCP或UDP,分别称之为TCP报文段(segment)或UDP用户数据报。
UDP在传送数据之前不需要先建立连接 。远地主机的运输层在收到UDP报文后,不需要给出任何确认。虽然UDP不提供可靠交付,但在某些情况下UDP却是一种最有效的工作方式。
TCP则提供面向连接的服务。 在传送数据之前必须先建立连接,数据传送结束后要释放连接。TCP不提供广播或多播服务。由于TCP要提供可靠的、面向连接的运输服务,因此不可避免地增加了许多的开销,如确认、流量控制、计时器以及连接管理等。这不仅使协议数据单元的首部增大很多,还要占用许多的处理机资源。
表5-1给出了一些应用和应用层协议主要使用的运输层协议(UDP或TCP)。
1.3 运输层的端口
前面已经提到过运输层的复用和分用功能。其实在日常生活中也有很多复用和分用的例子。假定一个机构的所有部门向外单位发出的公文都由收发室负责寄出,这相当于各部门都“复用”这个收发室。当收发室收到从外单位寄来的公文时,则要完成“分用”功能,即按照信封上写明的本机构的部门地址把公文正确进行交付。
运输层的复用和分用功能也是类似的。应用层所有的应用进程都可以通过运输层再传送到IP层(网络层),这就是复用。运输层从IP层收到发送给各应用进程的数据后,必须分别交付指明的各应用进程,这就是分用。 显然,给应用层的每个应用进程赋予一个非常明确的标志是至关重要的。
我们知道,在单个计算机中的进程是用进程标识符(一个不大的整数)来标志的。但是在互联网环境下,用计算机操作系统所指派的这种进程标识符来标志运行在应用层的各种应用进程则是不行的。这是因为在互联网上使用的计算机的操作系统种类很多,而不同的操作系统又使用不同格式的进程标识符。为了使运行不同操作系统的计算机的应用进程能够互相通信,就必须用统一的方法 (而这种方法必须与特定操作系统无关)对TCP/IP体系的应 用进程进行标志。
但是,把一个特定机器上运行的特定进程,指明为互联网上通信的最后终点还是不可行的。这是因为进程的创建和撤销都是动态 的,通信的一方几乎无法识别对方机器上的进程。另外,我们往往需要利用目的主机提供的功能来识别终点,而不需要知道具体实现这个功能的进程是哪一个 (例如,要和互联网上的某个邮件服务器联系,并不一定要知道这个服务器功能是由目的主机上的哪个进程实现的)。
解决这个问题的方法就是在运输层使用协议端口号( protocol port number) ,或通常简称为端口( port) 。 这就是说,虽然通信的终点是应用进程,但只要把所传送的报文交到目的主机的某个合适的目的端口,剩下的工作(即最后交付目的进程)就由TCP或UDP来完成。
请注意,这种在协议栈层间的抽象的协议端口是软件端口,和路由器或交换机上的硬件端口是完全不同的概念。硬件端口是不同硬件设备进行交互的接口,而软件端口是应用层的各种协议进程与运输实体进行层间交互的一种地址。不同的系统具体实现端口的方法可以是不同的(取决于系统使用的操作系统)。
在后面将讲到的UDP和TCP的首部格式中,我们将会看到(图5-5和图5-14) 它们都有源端口和目的端口这两个重要字段。当运输层收到IP层交上来的运输层报文时,就能够根据其首部中的目的端口号把数据交付应用层的目的应用进程。
TCP/IP的运输层用一个16位端口号来标志一个端口 。但请注意,端口号只具有本地意义,它只是为了标志本计算机应用层中的各个进程在和运输层交互时的层间接口。在互联网不同计算机中,相同的端口号是没有关联的。16位的端口号可允许有65535个不同的端口 号 ,这个数目对一个计算机来说是足够用的。
由此可见,两个计算机中的进程要互相通信,不仅必须知道对方的IP地址(为了找到 对方的计算机),而且要知道对方的端口号(为了找到对方计算机中的应用进程)。这和我们寄信的过程类似。当我们要给某人写信时,就必须在信封上写明他的通信地址(这是为了找到他的住所,相当于IP地址),并且还要写上收件人的姓名(这是因为在同一住所中可能有好几个人,这相当于端口号)。在信封上还写明自己的地址。当收信人回信时,很容易在信封上找到发信人的地址。互联网上的计算机通信是采用客户■服务器方式。客户在发起通信请求时,必须先知道对方服务器的IP地址和端口号。因此运输层的端口号分为下面的2 两大类。
(1) 服务器端使用的端口号 这里又分为两类,最重要的一类叫做熟知端口号( wellknown port number) 或系统端口号,数值为0-1023。这些数值可在网址www.iana.org查到。
IANA把这些端口号指派给了 TCP/IP最重要的一些应用程序,让所有的用户都知道。当一种新的应用程序出现后,IANA必须为它指派一个熟知端口,否则互联网上的其他应用进程就无法和它进行通信。表5-2给出了一些常用的熟知端口号。
另一类叫做登记端口号,数值为1024?49151 。这类端口号是为没有熟知端口号的应用程序使用的。使用这类端口号必须在IANA按照规定的手续登记,以防止重复。
(2) 客户端使用的端口号 数值为49152?65535 。由于这类端口号仅在客户进程运行时才动态选择,因此又叫做短暂端口号。这类端口号留给客户进程选择暂时使用。当服务器进程收到客户进程的报文时,就知道了客户进程所使用的端口号,因而可以把数据发送给客户进程。通信结束后,刚才已使用过的客户端口号就不复存在,这个端口号就可以供其他客户进程使用 。
2 UDP
3. TCP
由于TCP协议比较复杂,因此本节先对TCP协议进行一般的介绍,然后再逐步深入讨论TCP的可靠传输、流量控制和拥塞控制等问题。
3.1 TCP最主要的特点
TCP是TCP/IP体系中非常复杂的一个协议。下面介绍TCP最主要的特点。 ( 1) TCP是面向连接 的运输层协议。这就是说,应用程序在使用TCP协议之前,必须先建立TCP连接。在传送数据完毕后,必须释放已经建立的TCP连接。也就是说,应用进程之间的通信好像在“打电话”:通话前要先拨号建立连接,通话结束后要挂机释放连接。
(2)每一条TCP连接只能有两个端点(endpoint),每一条TCP连接只能是点对点 的(一对一)。这个问题后面还要进一步讨论。
(3) TCP提供可靠交付 的服务。通过TCP连接传送的数据,无差错、不丢失、不重复,并且按序到达。
(4) TCP提供全双工通信 。TCP允许通信双方的应用进程在任何时候都能发送数据。TCP连接的两端都设有发送缓存和接收缓存,用来临时存放双向通信的数据。在发送时,应用程序在把数据传送给TCP的缓存后,就可以做自己的事,而TCP在合适的时候把数据发送出去。在接收时,TCP把收到的数据放入缓存,上层的应用进程在合适的时候读取缓存中的数据。
(5)面向字节流。TCP中的“流”(stream)指的是流入到进程或从进程流出的字节序列。
“面向字节流”的含义是:虽然应用程序和TCP的交互是一次一个数据块(大小不等),但TCP把应用程序交下来的数据仅仅看成是一连串的无结构的字节流。TCP并不知道所传送的字节流的含义。TCP不保证接收方应用程序所收到的数据块和发送方应用程序所发出的数据块具有对应大小的关系 (例如,发送方应用程序交给发送方的TCP共10个数据块,但接收方的TCP可能只用了 4个数据块就把收到的字节流交付上层的应用程序 )。但接收方用程序收到的字节流必须和发送方应用程序发出的字节流完全一样。当然,接收方的应用程序必须有能力识别收到的字节流,把它还原成有意义的应用层数据。图5-8是上述概念的示意图。
为了突出示意图的要点,我们只画出了一个方向的数据流。但请注意,在实际的网络中,一个TCP报文段包含上千个字节是很常见的,而图中的各部分都只画出了几个字节,这仅仅是为了更方便地说明“面向字节流”的概念。另一点很重要的是:图5-8中的TCP连接是一条虚连接(也就是逻辑连接),而不是一条真正的物理连接。TCP报文段先要传送到IP层,加上IP首部后,再传送到数据链路层。再加上数据链路层的首部和尾部后,才离开主机发送到物理链路。
图5-8指出,TCP和UDP在发送报文时所采用的方式完全不同。TCP并不关心应用进程一次把多长的报文发送到TCP的缓存中,而是根据对方给出的窗口值和当前网络拥塞的程度来决定一个报文段应包含多少个字节(UDP发送的报文长度是应用进程给出的)。如果应用进程传送到TCP缓存的数据块太长,TCP就可以把它划分短一些再传送。如果应用进程一次只发来一个字节,TCP也可以等待积累有足够多的字节后再构成报文段发送出去。关于TCP报文段的长度问题,在后面还要进行讨论。
3.2 TCP的连接
TCP把连接作为最基本的抽象。TCP的许多特性都与TCP是面向连接的这个基本特性有关。因此我们对TCP连接需要有更清楚的了解。
前面已经讲过,每一条TCP连接有两个端点。那么,TCP连接的端点是什么呢?不是主机,不是主机的IP地址,不是应用进程,也不是运输层的协议端口。TCP连接的端点叫做套接字(socket)或插口。根据RFC 793的定义:端口号拼接到(concatenated with) IP地址即构成了套接字。因此,套接字的表示方法是在点分十进制的IP地址后面写上端口号,中间用冒号或逗号隔开。
例如,若IP地址是192.3.4.5而端口号是80,那么得到的套接字就是(19234.5:80)。总之,我们有套接字socket = (IP地址:端口号) (5-1)
每一条TCP连接唯一地被通信两端的两个端点(即两个套接字)所确定。即: TCP 连接::={socket 1, socket2} = {(IP1: port1), (IP2: port2)} (5-2)
这里IPi和IP2分别是两个端点主机的IP地址,而port1和port2分别是两个端点主机中的端口号。TCP连接的两个套接字就是socket1和socket?。可见套接字socket是个很抽象的概念。
4 可靠传输的工作原理
我们知道,TCP发送的报文段是交给IP层传送的。但IP层只能提供尽最大努力服务,也就是说TCP下面的网络提供的是不可靠传输,因此tcp必须采取适当的措施才能使得2个运输层之间的通信变得可靠:
- 传输不产生差错
这个原则就是采用差错校验 - 不管发送方以多快数据发送数据,接收方总是来得及处理收到的数据
这个原则就是停止等待协议,发送方根据接收方的ack(携带剩余的缓存空间),决定发送速度。避免发送超过接收端接收能力的数据量。
4.1 停止等待ARQ协议
先介绍简单的可高传输原理,首先是停止等待,即一发一收,收到后,再发下一条。这样明显效率低,浪费带宽。
1)无差错情况
发送发发送数据包,接收方在规定时间内收到,并且回复确认,发送发再次发送下一次数据报文
2)出现差错的情况 当B在接收M1时出现了差错,则B什么也不做,不通知A收到有差错的报文,也有可能是在传输过程中M1被丢失了,B不会发送任何的消息。这时ARQ规定只要A在一定的时间内没有收到B发来的确认报文,就需要进行超时重传 。
这样就解决了出现传输错误的问题。
要实现超时重传,发送方需要设定一个超时重传计时器,并且超时重传计时器的时间应该比数据包一次往返的时间更长一些,发送方还需要对发送完的分组进行备份,以便进行重传,并且需要对每一个数据包进行编号,这样才能在确认是哪一个报文段没有正确发送。
侧重接收错误
3)确认丢失和确认迟到
确认丢失 :确认消息在传输的过程中丢失了。当A向B发送M1时,B收到了M1并且发送确认消息,但是这个确认消息在传输的过程中丢失了,当超时重传计时器的时间到时,A重新发送M1,B收到时应该做:①收到但是丢弃M1,不向上层交付②重新发送确认消息,不会因为发过了M1的确认就不进行发送确认迟到 :确认消息在传输过程中被滞留了,同样当A没有在超时重传计时器时间允许的范围内收到B发来的确认消息,需要进行对M1重传,同样的B收到后需要对M1丢弃并且重新发送确认报文,而A可能此时收到了滞留的确认消息,则直接丢弃
侧重收到了消息,但是ack出现错误
自动重传请求(ARQ) 是OSI模型中数据链路层和运输层的错误纠正协议,通过确认和超时这两个机制,可以实现在不可靠服务的基础上实现可靠的信息传输,当然,ARQ包括停止等待ARQ 和连续ARQ协议 这2种。
4.2 连续ARQ协议
核心就是发送窗口概念,可以同时多发几个,而不是停止等待协议那样一发一收,必须等待。
连续ARQ协议可以提供信道利用率,发送发维持一个发送窗口例如大小为5,那么也就是说发送方可以一次性发送5个连续的数据报而不需要等待对方的确认。接收方采取累积确认的方式,只需要发送最后一个序列的确认报文,那么发送方即认为接收方收到了该序号之前的所有报文,例如发送发发送了编号为1-5序号的报文,而接收方只需要发送序号为5的确认报文,发送方即认为接收方正确接收到了1-5这个报文段
采用上面方法的优点是信道利用率高容易实现,缺点是不能向发送方反映出接收方已经正确收到的所有分组信息,例如发送方发了5个分组,而接收方丢失了第三个分组,只能对前两个报文进行确认,而发送方只好将后面三个分组都进行重传这就叫做Go-Back-N(回退N)
5 TCP的首部报文格式
TCP是面向字节的,但是具体发送的数据还是报文段,而报文段首部的各字段的作用体现了TCP的全部功能,下面介绍一些比较常用到得报文数据段 :
-
源端口与目的端口:源端口与目的端口各占2个字节,这两个字段是用于分用和复用的标记了进程的端口号,在接收或者发送时就能进行封包和解包 -
序号:序号占4个字节,总共是2^32个序号,当序号用完时可以从0接着编号,在每一个TCP连接中发送的字节流都必须按顺序编号,整个字节流的起始编号必须在建立连接时确定 -
确认号:确认号占4个字节,是期望收到对方下一个报文段的第一个数据字节的序号,也就是说如果确认号为N,则代表在N-1之前的数据都已经确认收到 -
确认ACK:仅当ACK=1时,字段才有效,TCP规定,在连接建立之后必须把ACK=1 -
同步SYN:在连接建立时用来同步需要,当SYN=1而ACK=0时,表明这是一个连接请求报文段,对方若同意建立连接,则在响应数据报里发送SYN=1和ACK=1 -
终止FIN:用来释放一个连接,当FIN=1时表明此连接需要被释放 -
窗口:占2个字节,是指接收方的接收窗口,窗口值告诉发送方:本次发送最多只能发送的数据量大小,因此窗口作为发送方的发送窗口的大小依据
6 TCP可靠传输的实现
这里是具体的实现,基于前面讲的原理,会更加的细节。
- 以直接为单位的滑动窗口
- 超时重传时间的选择
- 选择确认SACK
SACK可以只重传缺失的部分,但是多数的实现还是重传所有未被确认的数据块
7. 流量控制
要想传输的速度快,应该需要发送方和接收方的共同努力,但是如果发送方过快而接收方来不及接收的话,就需要进行流量控制,而流量控制是靠滑动窗口来实现的 ,其实也就是报文格式里面的窗口字段,接收方发送的确认报文中的窗口字段可以用来控制发送方窗口的大小,从而影响发送方的发送速率。
接收方给发送方的ack含有窗口的大小,因此,可以避免传输超量的数据
假如接收方B发向发送方A发送了一个窗口为0的确认报文,这就告诉发送方A不能再发送数据了,这里考虑一种情况,假如过了一段时间后接收方B的缓冲区可以接收新的数据,从而向发送方发A送一个窗口值rwnd=100的报文,但是这个报文丢失了,这就导致发送方A一直在等待接收方给的非零窗口值,而接收方B一直等待发送方发送新的数据,造成了一种死锁的现象,为了解决这个问题,TCP为每一个连接设置有 持续计时器`,只要发送方收到零窗口的通知就启动计时器,当计时器的时间到是就发送一个探测报文,然后接收方在进行确认给出当前的窗口值这就不会造成一直僵持的状态了
8. TCP的拥塞控制
8.1 什么是拥塞控制
拥塞控制是为了防止过多的数据注入到网络中,这样可以使网络中的路由器或者链路不至过载,拥塞控制是一个全局性的过程涉及到所有的主机、路由器等等。而相反流量控制需要做的是点对点的控制,流量控制需要做的是抑制发送方的发送速率,以便接收方来的及接受
流量控制是针对某个点的,防止接收端被撑爆了,而拥塞是指存在100个接收方,同一时间发送方都给他们发数据,虽然单个点的量不多,但是总和多,把网络撑爆了。
8.2 如何避免拥塞
TCP进行拥塞控制的算法有四种,慢开始、拥塞避免、快恢复和快重传,下面结合下图进行介绍
-
慢开始 :当主机开始发送数据的时候,并不清楚网络中的拥塞程度,如果这时候将大量的数据注入到网络中可能会造成拥塞,所以采取类一种慢慢开始的算法,由小到大增加窗口值的大小。并且设置一个ssthresh慢开始门限,在慢开始阶段每经过一个传播轮次窗口值加倍 -
拥塞避免 :当当前窗口值到达慢开始门限时,开始使用拥塞避免算法,拥塞避免算法的思路是让窗口值慢慢的增加,每经过一个RTT时间窗口值就加1,也就是按线性规律增长。根据图当窗口值到达24时出现了一个新情况,超时了,这时候发送方判断出现了拥塞,于是将当前窗口值cwnd=1,满开始门限ssthresh=24/2=12,重新进行慢开始算法以及拥塞控制算法 -
快重传与快恢复 :快重传算法要求接收方不要进行捎带确认,而是要进行立即确认,当发送发一连收到三个确认报文时,发送方就知道某个报文端没有发送成功,于是立即使用快重传,重新发送丢失的数据包,同时进行快恢复算法将当前窗口cwnd改为之前的一半 快重传:快速识别丢失的数据,避免使用超时策略,苦苦的等待,因为超时策略效率低 快恢复:cwnd不再从1开始,避免恢复很慢
上面的流程图如下:
9. TCP的运输连接管理
9.1 三次握手
上面多次提到TCP是面向连接的,所以需要连接的建立与释放,下面就来聊一聊TCP的连接建立的过程
在一个TCP的连接建立的生命周期里,一共有以下几种状态:
- LISTEN:等待来自任何远程TCP的连接
- SYN-SEND:发送连接请求后等待匹配的连接请求
- SYN-RECEIVED:表示已接收并方连接请求后等待连接确认,也就是第二次握手的状态
- ESTAB-LISHED:表示连接已经创建成功可以进行数据的传输
如上图是三次握手的连接示意图,TCP规定在客户发起请求连接的时候,不能发送数据而是要消耗掉一个序号,下面来分析一下上面的过程:
-
客户端主动向服务器端发送连接请求,请求中首部同部位SYN=1,同时选择一个初始序号seq,SYN报文段不允许携带数据,只消耗一个序号,此时客户端进入SYN-SEND状态 -
服务器端收到客户端发起连接的请求后,需要确认客户端的报文,在确认报文段中需要把SYN和ACK都置一,同时发送一个确认号,也为自己选择一个初始序号,这个报文段也是不能携带数据的,需要消耗一个序号,同时服务器进入SYN-RECEIVED -
客户端在收到确认报文之后,还需要给出确认连接报文,确认连接报文找那个的ACK=1,序号为x+1,这个报文可以携带数据,同时客户端进入ESTAB-LISHED -
服务器收到确认报文后也进入ESTAB-LISHED
再次分析三次握手的过程,其实建立连接的请求的过程无非是先让对方都知道自己的状态,也就是要让确定对方发送和接收都正常:
- 第一次握手:客户端什么也确认不了,服务器端确认:对方发送正常,自己接收正常
- 第二次握手:客户端确认:自己接收,发送都正常,对方发送,接收也正常,服务器端确认:对方发送正常,自己接收正常
- 第三次握手:客户端确认:自己接收,发送都正常,对方发送,接收也正常,服务器端确认:自己接收,发送都正常,对方发送,接收也正常
2次握手可以吗
不可以,假设采用2次握手。
假设 A给B发送连接请求,A1,但是网络原因比较慢,导致B没有及时回ack1,那么A就会重新发送一个A2,A2先于A1到达,A2连接成功后,数据也完成了发送,并断开连接。此时A1请求才到B,那么B会误以为这个是新的连接,那么就会新建立连接,并等待A给他发消息,而此时A认为A1是失效的,不可能向B发消息,这样就浪费资源。
如果采用3次,就可以避免。
9.2 4次挥手
- 客户端应用程序发出释放连接的请求报文段,主动关闭连接,报文段首部的FIN=1,不包含数据其中seq=u,此时客户端进入FIN-WAIT-1
- 服务器收到客户端发来的连接释放报文后,发出确认应答报文,其中ACK=1,生成自己的序列号,然后服务器主机就进入CLOSE-WAIT
- 客户端收到服务器发来的确认报文后,进入FIN-WAIT-2状态,等待服务器发出连接释放的报文段,此时客户端到服务器端的连接已经释放
- 当服务器主机没有数据发送的时候,服务器主机发出断开连接的请求报文段其中ACK=1,FIN=1,其中seq不一定是v因为中间可能还发送了数据,发送完请求之后,服务器就进入到LAST-ACK
- 客户端收到服务器发出的连接断开请求后,客户端需要作出相应,然后进入到TIME-WAIT状态,此时连接还没有关闭,必须经过时间2MSL之后,客户端才会进入CLOSE
在一个TCP的连接关闭生命周期里面有以下几种状态:
- FIN-WAIT-1:表示等待来自远程TCP的连接终止请求,或者等待先前发送的连接终止请求
- FIN-WAIT-2:表示等待来自远程TCP的连接终止请求
- CLOSE-WAIT:表示等待本地用户的连接终止请求
- CLOSING:表示等待来自远程TCP的连接终止请求确认
- LAST-ACK:表示等待先前发送给远程TCP的连接终止请求的确认
- TIME-WAIT:表示等待足够的时间以确保远程TCP收到其连接终止确认的请求
- CLOSE:表示连接已经关闭,无连接状态
需要四次挥手的原因是任何一方都可以在传输数据结束之后发出释放连接的请求,当对方确认之后进入到半关闭状态,当另外一方也没有数据发送的时候则再次发出连接释放请求,因此需要四次。
其实就是2组send msg和ack msg,分别是A告诉B,此时A没有数据发给B了,B回一个ack,此时B仍可以向A发送数据。然后当B没有数据发给A后,B就发个通知消息给A,A回一个ack。
为什么A在TIME-WAIT状态必须经过时间2MSL之后,客户端才会进入CLOSE?
①为了保证最后一个响应能够到达服务端 ②防止失效的报文段,等待过2MSL时间之后可以确保本连接持续时间内的所有报文段都从网络上消失
|