TCP三次握手与四次挥手详解(最全面)

TCP的三次握手与四次挥手

TCP报文段的首部格式

  • 源端口和目的端口字段各占 2个字节。端口是运输层与应用层的服务接口。运输层的复用和分用功能都要经过端口才能实现。
  • 序号字段4字节。TCP链接中传送的数据流中的每个字节都编上一个序号。序号字段的值则指的是本报文段所发送的数据的第一个字节的序号。
  • 确认号字段占 4字节,是指望收到对方的下一个报文段的数据的第一个字节的序号
  • 数据偏移(即首部长度)占 4位,它指出TCP报文段的数据起始处距离TCP报文段的起始处有多远。“数据偏移”的单位是32位字(以4字节为计算单位)
  • 保留字段6位,保留为从此使用,但目前应置为0。
  • 紧急URGURG= 1 时,代表紧急指针字段有效。它告诉系统此报文段中有紧急数据,应尽快传送(至关于高优先级的数据)。
  • 确认 ACK 只有当ACK= 1 时确认号字段才有效。当ACK= 0 时,确认号无效
  • 推送 PSH(PuSH)接收TCP收到PSH= 1 的报文段,就尽快地交付接收应用进程,而再也不等到整个缓存都填满了后再向上交付。
  • 复位 RST(ReSeT)当RST= 1 时,代表TCP链接中出现严重差错(如因为主机崩溃或其余缘由),必须释放链接,而后再从新创建运输链接。
  • 同步 SYN 同步SYN= 1 表示这是一个链接请求或链接接受报文。
  • 终止 FIN(FINis) 用来释放一个链接。FIN= 1 代表此报文段的发送端的数据已发送完毕,并要求释放运输链接。
  • 窗口字段占2字节,用来让对方设置发送窗口的依据,单位为字节
  • 检验和占2字节。检验和字段检验的范围包括首部和数据这两部分。在计算检验和时,要在TCP报文段的前面加上12字节的伪首部。
  • 紧急指针字段占16位,指出在本报文段中紧急数据共有多少个字节(紧急数据放在本报文段数据的最前面)。
  • 选项字段长度可变。TCP最初只规定了一种选项,即最大报文段长度 MSS。MSS告诉对方TCP:“个人缓存所能接收的报文段的数据字段的最大长度是MSS个字节。
  • 填充字段这是为了使整个首部长度是4字节的整数倍

TCP的工做原理

注意:算法

  • 在发送完一个分组后,必须暂时保留已发送的分组的副本。缓存

  • 分组和确认分组都必须进行编号。服务器

  • 超时计时器的重传时间应当比数据在分组传输的平均往返时间更长一些。网络

TCP 的流量控制

通常说来,咱们老是但愿数据传输得更快一些。但若是发送方把数据发送得过快,接收方就可能来不及接收,这就会形成数据的丢失。tcp

流量控制(flow control)就是让发送方的发送速率不要太快,既要让接收方来得及接收,也不要使网络发生拥塞。性能

利用滑动窗口机制能够很方便地在 TCP 链接上实现流量控制。指针

举个例子:blog

TCP的拥塞控制

在某段时间,若对网络中某资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏——产生拥塞(congestion)。接口

出现资源拥塞的条件:

​ 对资源需求的总和 > 可用资源

若网络中有许多资源同时产生拥塞,网络的性能就要明显变坏,整个网络的吞吐量将随输入负荷的增大而降低。

拥塞控制与流量控制的关系

拥塞控制所要作的都有一个前提,就是网络可以承受现有的网络负荷。

拥塞控制是一个全局性的过程,涉及到全部的主机、全部的路由器,以及与下降网络传输性能有关的全部因素。

流量控制每每指在给定的发送端和接收端之间的点对点通讯量的控制。

流量控制所要作的就是抑制发送端发送数据的速率,以便使接收端来得及接收。

拥塞控制所起的做用

慢开始和拥塞避免

发送方维持一个叫作拥塞窗口 cwnd (congestion window)的状态变量。拥塞窗口的大小取决于网络的拥塞程度,而且动态地在变化。

发送方让本身的发送窗口等于拥塞窗口。如再考虑到接收方的接收能力,则发送窗口还可能小于拥塞窗口。

发送方控制拥塞窗口的原则是:只要网络没有出现拥塞,拥塞窗口就再增大一些,以便把更多的分组发送出去。但只要网络出现拥塞,拥塞窗口就减少一些,以减小注入到网络中的分组数。

慢开始算法的原理

在主机刚刚开始发送报文段时可先设置拥塞窗口 cwnd = 1,即设置为一个最大报文段 MSS 的数值。

在每收到一个对新的报文段的确认后,将拥塞窗口加 1,即增长一个 MSS 的数值。

用这样的方法逐步增大发送端的拥塞窗口 cwnd,可使分组注入到网络的速率更加合理。

发送方每收到一个对新报文段的确认(重传的不算在内)就使 cwnd加

三次握手创建TCP链接

第一次握手:A 的 TCP 向 B 发出链接请求报文段,其首部中的同步位 SYN = 1,并选择序号 seq = x,代表传送数据时的第一个数据字节的序号是 x。

第二次握手:B 的 TCP 收到链接请求报文段后,如赞成,则发回确认。B 在确认报文段中应使 SYN = 1,使 ACK = 1,其确认号ack = x + 1,本身选择的序号 seq = y。

第三次握手:

  • A 收到此报文段后向 B 给出确认,其 ACK = 1,确认号 ack = y + 1。A的TCP通知上层应用进程,链接已经创建。
  • B 的 TCP 收到主机 A 的确认后,也通知其上层应用进程:TCP 链接已经创建。

四次挥手释放TCP链接

第一次挥手:

  • 数据传输结束后,通讯的双方均可释放链接。如今 A 的应用进程先向其 TCP 发出链接释放报文段,并中止再发送数据,主动关闭 TCP 链接。

  • A 把链接释放报文段首部的 FIN = 1,其序号seq = u,等待 B 的确认。

第二次挥手:

  • B 发出确认,确认号 ack = u + 1,而这个报文段本身的序号 seq = v。
  • TCP 服务器进程通知高层应用进程。
  • 从 A 到 B 这个方向的链接就释放了,TCP 链接处于半关闭状态,B若发送数据,A仍是要接收的

第三次挥手:

  • 若 B 已经没有要向 A 发送的数据,其应用进程就通知 TCP 释放链接

第四次挥手:

  • A 收到链接释放报文段后,必须发出确认。 •在确认报文段中 ACK = 1,确认号 ack = w + 1,本身的序号 seq = u + 1。

常见面试题

为何TCP链接的时候是三次握手,关闭的时候倒是四次握手?

答:

由于当Server端收到Client端的SYN链接请求报文后,能够直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。

可是关闭链接时,当Server端收到FIN报文时,极可能并不会当即关闭SOCKET,因此只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端全部的报文都发送完了,我才能发送FIN报文,所以不能一块儿发送。故须要四步握手。

为何不能用两次握手进行链接?

答:

3次握手完成两个重要的功能,既要双方作好发送数据的准备工做(双方都知道彼此已准备好),也要容许双方就初始序列号进行协商,这个序列号在握手过程当中被发送和确认。

如今把三次握手改为仅须要两次握手,死锁是可能发生的。做为例子,考虑计算机S和C之间的通讯,假定C给S发送一个链接请求分组,S收到了这个分组,并 发送了确认应答分组。按照两次握手的协定,S认为链接已经成功地创建了,能够开始发送数据分组。但是,C在S的应答分组在传输中被丢失的状况下,将不知道S 是否已准备好,不知道S创建什么样的序列号,C甚至怀疑S是否收到本身的链接请求分组。在这种状况下,C认为链接还未创建成功,将忽略S发来的任何数据分 组,只等待链接确认应答分组。而S在发出的分组超时后,重复发送一样的分组。这样就造成了死锁。

若是已经创建了链接,可是客户端忽然出现故障了怎么办?

答:

TCP还设有一个保活计时器,显然,客户端若是出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会从新复位这个计时器,时间一般是设置为2小时,若两小时尚未收到客户端的任何数据,服务器就会发送一个探测报文段,之后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭链接。

为何TIME_WAIT状态须要通过2MSL(最大报文段生存时间)才能返回到CLOSE状态?

答:

虽然按道理,四个报文都发送完毕,咱们能够直接进入CLOSE状态了,可是咱们必须假象网络是不可靠的,有能够最后一个ACK丢失。因此TIME_WAIT状态就是用来重发可能丢失的ACK报文。在Client发送出最后的ACK回复,但该ACK可能丢失。Server若是没有收到ACK,将不断重复发送FIN片断。因此Client不能当即关闭,它必须确认Server接收到了该ACK。Client会在发送出ACK以后进入到TIME_WAIT状态。Client会设置一个计时器,等待2MSL的时间。若是在该时间内再次收到FIN,那么Client会重发ACK并再次等待2MSL。所谓的2MSL是两倍的MSL(Maximum Segment Lifetime)。MSL指一个片断在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。若是直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP链接。

相关文章
相关标签/搜索