本文主要整理TCP协议的知识点算法
尽管TCP和UDP都使用相同的网络层(IP), TCP却向应用层提供与UDP彻底不一样的服务。TCP提供一种面向链接的、可靠的字节流服务。缓存
TCP具备如下特色安全
一、面向链接 每一个TCP段都包含一个源端口号和目的端口号,用来肯定发送端和接收端的应用进程,而后结合IP首部中的源端IP地址和目的端IP地址就能惟一肯定一个TCP链接。网络
二、可靠 TCP协议拥有各类机制来确保数据传送的可靠性,例如超时重传策略,保持首部和数据的校验和,流量控制和校验已收到数据的完整性和正确性等。并发
TCP报文段被封装到IP数据报中,一般是20个字节。函数
源端口号和目的端口号:用于寻找发送端和接收端的应用进程,分别是16位性能
Sequence Number(序列号):报文段中的第一个字节,用于标识发送的数据字节流大数据
Acknowledgment Number(确认号):确认序列号包含发送确认的一端所指望收到的下一个序号,所以,确认序号应当是上次已成功收到数据字节序号加1。不过,只有当标志位中的ACK标志为1时该确认序列号的字段才有效。指针
Offset(数据偏移):给出首部中32 bit字的数目,须要这个值是由于任选字段的长度是可变的。这个字段占4bit(最多能表示15个32bit的的字,即4*15=60个字节的首部长度),所以TCP最多有60字节的首部。然而,没有任选字段,正常的长度是20字节;cdn
TCP Flags:TCP首部中有6个标志比特,它们中的多个可同时被设置为1,主要是用于操控TCP的状态机的,依次为URG,ACK,PSH,RST,SYN,FIN。每一个标志位的意思以下:
URG:此标志表示TCP包的紧急指针域有效,用来保证TCP链接不被中断,而且督促中间层设备要尽快处理这些数据;
ACK:此标志表示应答域有效,就是说前面所说的TCP应答号将会包含在TCP数据包中;有两个取值:0和1,为1的时候表示应答域有效,反之为0;
PSH:这个标志位表示Push操做。该标志通知接收方将接收到的数据所有提交给接收进程。这里所说的数据包括与此PUSH包一块儿传输的数据以及以前就为该进程传输过来的数据。
RST:这个标志表示链接复位请求。用来复位那些产生错误的链接,也被用来拒绝错误和非法的数据包;
SYN:表示同步序号,用来创建链接。SYN标志位和ACK标志位搭配使用,当链接请求的时候,SYN=1,ACK=0;链接被响应的时候,SYN=1,ACK=1;这个标志的数据包常常被用来进行端口扫描。扫描者发送一个只有SYN的数据包,若是对方主机响应了一个数据包回来 ,就代表这台主机存在这个端口;可是因为这种扫描方式只是进行TCP三次握手的第一次握手,所以这种扫描的成功表示被扫描的机器不很安全,一台安全的主机将会强制要求一个链接严格的进行TCP的三次握手;
FIN:用来结束一个TCP回话.但对应端口仍处于开放状态,准备接收后续数据。
Window(窗口大小):窗口大小,也就是有名的滑动窗口,用来进行流量控制。
CheckSum(校验和):检验和是一个强制性字段,是由发送端计算和保存,而后由接收端进行校验
Urgent Pointer(紧急指针):只有当URG标志置1时紧急指针才有效。紧急指针是一个正的偏移量,和序号字段中的值相加表示紧急数据最后一个字节的序号。TCP的紧急方式是发送端向另外一端发送紧急数据的一种方式。
TCP数据部分是可选的,在创建和终止链接等状况下就会发送不带数据部分的报文段
TCP是一个面向链接的协议,一方向另外一方发送数据,必须先在双方之间创建一条链接。
TCP链接的创建---三次握手
(1)客户端执行主动打开操做,向服务端发送SYN报文,指明打算链接的服务端的端口,以及初始序号(ISN),而后进入SYN_SENT状态。其中ISN随时间而变化,因此不一样的链接都将具备不一样的ISN。
(2)服务端收到SYN报文后,一样向客户端发回一个带有本身初始序号的SYN报文段,同时将ACK字段设为客户端ISN+1的值,做为对客户端SYN报文的确认响应,而后本身进入SYN_RCVD状态。
(3)客户端一样将ACK字段设为服务端ISN+1的值,做为对服务端SYN报文的确认响应,本身进入ESTABLISHED状态,服务端收到客户端的确认响应后,也进入ESTABLISHED状态。
链接创建成功后,双方则可以发送数据,接收方则发送ACK报文做为确认响应。
TCP链接的断开---四次挥手
创建链接须要三次交互,而断开链接则须要四次交互,这是因为TCP链接是一个全双工链接,须要双方单独来进行关闭,收到FIN报文意味着在这个方向上没有数据流动,可是仍然能够发送数据。
(1)应用关闭,须要断开TCP链接,则向服务端发送FIN报文,并进入FIN_WAIT_1状态;
(2)服务端收到客户端发送的FIN请求,则回发ACK,ACK序列号为ACK加1,进入CLOSE_WAIT状态;客户端收到ACK确认回应后,进入FIN_WAIT_2状态。此时,客户端没法发送数据,可是仍可接收服务端发来的数据,这种状态称为半关闭状态。
(3)服务端不须要发送数据时,则向客户端发送FIN请求断开链接,进入LAST_ACK状态,客户端收到断开请求,回应ACK,进入TIME_WAIT状态;服务端收到ACK后,进入CLOSED,今后TCP链接成功断开。
TCP所谓的“链接”,实际上是通信双方维护的一种状态,看上去像是链接同样,这就涉及到TCP链接过程当中,通信双方不一样状态的装换。
TIME_WAIT 状态
也称为2MSL等待状态,每一个具体TCP实现必须选择一个报文段最大生存时间MSL。它是任何报文段被丢弃前在网络内的最长时间。对一个具体实现所给定的MSL值,处理的原则是:当TCP执行一个主动关闭,并发回最后一个ACK,该链接必须在TIME_WAIT状态停留的时间为2倍的MSL。这样可以让TCP再次发送最后的ACK以防这个ACK丢失(另外一端超时并重发最后的FIN)。
FIN_WAIT_2 状态
在FIN_WAIT_2状态咱们已经发出了 FIN,而且另外一端也已对它进行确认。除非咱们在实行半关闭,不然将等待另外一端的应用层意识到它已收到一个文件结束符说明,并向咱们发一个 FIN 来关闭另外一方向的链接。只有当另外一端的进程完成这个关闭,咱们这端才会从FIN_ WAIT_2状态进入TIME_WAIT状态。
这意味着咱们这端可能永远保持这个状态。另外一端也将处于 CLOSE_WAIT状态,并一直保持这个状态直到应用层决定进行关闭。
TCP首部中的RST位,用于“复位”,主要在下列三个场景中:
(1)到不存在的端口的链接请求
当链接请求到达时,目的端口没有进程正在监听,这个时候,就会发回RST报文告诉请求端;
(2)异常终止一个链接
客户端断开链接时,有可能不是经过发送FIN报文,而是发送RST进行复位,这称为异常释放。异常终止一个链接对应用程序来讲有两个优势:
丢弃任何待发数据并当即发送复位报文段;
RST的接收方会区分另外一端执行的时异常关闭仍是正常关闭。
(3)检测半打开链接
若是一方已经关闭或异常终止链接而另外一方却还不知道,咱们将这样的 T C P链接称为半
打开。 任何一端的主机异常均可能致使发生这种状况。只要不打算在半打开链接上传输数据,仍处于链接状态的一方就不会检测另外一方已经出现异常。
两个应用程序同时彼此执行主动打开的状况是可能的,尽管发生的可能性极小。每一方
必须发送一个 SYN,且这些SYN必须传递给对方。 这又称为同时打开。
当出现同时打开的状况时,两端几乎在同时发送 SYN,并进入SYN_SENT状态。当每一端收到 SYN时,状态变为 SYN_RCVD,同时它们都再发SYN并对收到的 SYN进行确认。当双方都收到 SYN及相应的ACK时,状态都变迁为ESTABLISHED 。一个同时打开的链接须要交换4个报文段,比正常的三次握手多一个。
当应用层发出关闭命令时,两端均从ESTABLISHED变为FIN_WAIT_1。这将致使双方各发送一个FIN,两个FIN通过网络传送后分别到达另外一端。收到FIN后,状态由FIN_WAIT_1变迁到 CLOSING,并发送最后的 ACK。当收到最后的 ACK时,状态变化为TIME_WAIT 。同时关闭和正常关闭使用的段交换数目相同。
TCP与UDP的区别至关大,它充分体现了数据传输时各类控制功能,能够进行丢包时的重发控制,还能够对次序乱掉的分包进行顺序控制。TCP经过校验和、序列号、确认应答、重发控制、链接管理以及窗口控制等机制实现可靠性传输。
在创建TCP链接的同时,也能够肯定发送数据包的单位,咱们也能够称为“最大消息长度”(MSS:Maximum Segment Size),最理想的状况时,最大消息长度正好是IP中不会被分片处理的最大数据长度。
TCP在发送数据时,会以MSS大小为单位对数据进行分割发送。MSS大小在三次握手时计算所得,两端发送创建链接的请求时,会在TCP首部中写入MSS选项,选二者较小的值。
TCP以一个段为单位发送数据,每发送一个段就会接收到一个确认应答的处理,这样容易形成传输负载变重,段的往返时间越长,性能越低。为了解决这一缺点,TCP引入了“窗口”的概念,发送端在发送了一个报文段后没必要要一直等待确认应答,而是继续发送。
窗口大小指无需等待确认应答而能够继续发送数据的最大值,图中窗口大小是4个报文段。
该图①中,能够看到滑动窗口的大小是4个报文段,报文段1001之前,接收端已经确认应答,报文段5001是未发送的数据,中间的报文段则是已经发送完成,正在等待确认应答的部分。当接收端确认数据后,这个滑动窗口不断的往右移动,窗口两个边沿的相对运动增长或减小了窗口的大小。
(1)窗口左边沿向右边沿靠近为窗口合拢。这种现象发生在数据被发送和确认时。
(2)窗口右边沿向右移动,将容许发送更多的数据,称为窗口张开。这种现象发生在接收端读取了已经确认的数据并释放了TCP的接收缓存。图③中则说明发送端已经收到了接收端的确认应答,窗口向右移动。
若是左边沿达到右边沿,则称为一个零窗口,此时发送方不可以发送任何数据。
TCP提供可靠的运输层。它使用的方法之一就是确认从另外一端收到的数据。但数据和确认都有可能会丢失。 TCP经过在发送时设置一个定时器来解决这种问题。若是当定时器溢出时尚未收到确认,它就重传该数据。 当使用了窗口控制,某些确认应答即使丢失也无需重发。
其次,当某一个报文段在传输的过程当中丢失,接收端若是收到一个本身应该接收序号之外的数据时,会针对当前为止收到的数据返回确认应答,通知发送端下一个要发送的数据序号,若是发送端连续3次收到同一个确认应答,则会对其对应的数据进行重发,无需等待超时定时器溢出,这就是快速重传算法。
有这样一种场景,发送端按照本身的实际状况来发送数据,可是接收端可能处理数据包的能力比较弱,或者一直在处理其余事情,没法接收任何的数据,此时,发送端发来的数据就会被丢弃,从而又会触发重发机制,形成资源的浪费。
为了解决这个问题,TCP提供了一种机制,可让发送端根据接收端的实际接收能力来控制发送的数据量,这就是流控制。在TCP首部中,有专门的字段来通知窗口的大小。在接收端发送确认应答报文时,会在窗口大小字段中标明本身目前的接收能力。不过,接收端的这个缓存区一旦溢出,窗口大小的值随即被设置为一个更小的值来通知给发送端。这就造成了一个完整的TCP流控制。
若是接收端发送的窗口更新通知丢失,则双发可能由于等待对方而使链接终止:发送方等待容许它继续发送数据的窗口更新,接收方等待接收数据。这样就会形成死锁,致使没法继续通讯,为避免此类问题的发生,发送端使用一个坚持定时器,定时发送一个窗口探测数据段,以获取最新的窗口大小的值。
有了TCP的窗口控制,收发主机之间即便再也不以一个数据段为单位发送确认应答,也可以连续发送大量数据包,但在网络出现拥堵时,忽然发送一个较大的数据,极有可能致使整个网络的瘫痪。为了防止该问题出现,TCP引入了“拥塞窗口”概念,而且经过“慢启动”算法,用来调节发送端所要发送的数据量。
当创建TCP链接时,拥塞窗口被初始化为1个报文段,每收到一个ACK,拥塞窗口的值就加1,在发送数据包时,将拥塞窗口的大小和接收端的通知窗口大小作比较,取较小的值,发送比该值还要小的数据量。随着包的往返发送,拥塞窗口以指数函数增加,拥堵情况激增,可能致使网络拥塞的发生。为了解决该问题,TCP引入了“慢启动阈值”的概念,当拥塞发生(超时或收到重复确认) 时,将慢启动阈值设置成拥塞窗口的一半,只要拥塞窗口的值超出这个阈值,则只容许如下面比例放大拥塞窗口:
此外,若是是超时引发了拥塞,则拥塞窗口被设置为1个报文段(这就是慢启动)。当新的数据被对方确认时,就增长拥塞窗口,但增长的方法依赖于咱们是否正在进行慢启动或拥塞避免。若是拥塞窗口小于或等于慢启动阈值,则正在进行慢启动,不然正在进行拥塞避免。慢启动一直持续到咱们回到当拥塞发生时所处位置的一半的时候才中止,而后转为执行拥塞避免。
(1)Nagle算法
该算法是指发送端即便还有应该发送的数据,可是若是这部分数据不多的话,则延迟发送。仅在知足如下两种条件中任意一种条件才能发送数据,不然暂时等待:
已发送的数据都已经收到确认应答;
能够发送最大段长度MSS的数据。
(2)延迟确认应答
若是接收端每次马上回复确认应答,可能会返回一个较小的窗口,由于刚接收完数据,缓存区已满。当发送端收到这个较小的窗口后,则会以它为上限发送数据,下降了网络利用率。
(3)捎带应答
TCP的确认应答通常会和回执数据一块儿回发给发送端,这样能够减小收发的数据量。