vlambda博客
学习文章列表

【015】十分钟搞懂计算机网络TCP协议



Java面试总结—第15篇




本章节知识点:

  • TCP和UDP的区别

  • TCP保证可靠的机制

  • TCP的流量控制、拥塞控制、ARQ协议

  • TCP的三次握手和四次挥手


    TCP、UDP是传输层的主要协议之一


01

TCP和UDP的区别


TCP




    TCP 的优点:可靠,稳定. TCP 的可靠体现在 TCP 在传递数据之前,会有三次握手来建立连接,而且在数据传递时,有确认、窗口、重传、拥塞控制机制,在数据传完后,还会断开连接用来节约系统资源。


    TCP 的缺点:慢,效率低,占用系统资源高,易被攻击 ,TCP 在传递数据之前,要先建连接,这会消耗时间,而且在数据传递时,确认机制、重传机制、拥塞控制机制等都会消耗大量的时间,而且要在每台设备上维护所有的传输连接,事实上,每个连接都会占用系统的 CPU、内存等硬件资源。而且,因为 TCP 有确认机制、三次握手机制,这些也导致 TCP 容易被人利用,实现 DDOS、CC 等攻击。


    总结:


  • 面向连接。


  • 每一条 TCP 连接只能是点对点的(一对一)。


  • 提供可靠交付的服务 (无差错,不丢失,不重复,且按序到达)(校验和、重传控制、序号标识、滑动窗口、确认应答实现可靠传输。如丢包时的重发控制,还可以对次序乱掉的分包进行顺序控制。)。


  • 提供全双工通信。


  • 面向字节流。


UDP




    UDP 的优点:快,比 TCP 稍安全 UDP 没有 TCP 的握手、确认、窗口、重传、拥塞控制等机制,UDP 是一个无状态的传输协议,所以它在传递数据时非常快。没有 TCP 的这些机制,UDP 较 TCP 被攻击者利用的漏洞就要少一些。但 UDP 也是无法避免攻击的,比如:UDP Flood 攻击……


    UDP 的缺点: 不可靠,不稳定 因为 UDP 没有 TCP 那些可靠的机制,在数据传递时,如果网络质量不好,就会很容易丢包。


    总结:


  • 无连接。


  • 尽最大努力交付 (不保证可靠交付)。


  • 面向报文。


  • 无拥塞控制。


  • 支持一对一、一对多、多对一和多对多的交互通信。


  • 首部开销小(只有四个字段:源端口、目的端口、长度、检验和)。


使用场景




    使用 TCP:当对网络通讯质量有要求的时候,比如:整个数据要准确无误的传递给对方,这往往用于一些要求可靠的应用,比如 HTTP、HTTPS、FTP 等传输文件的协议,POP、SMTP 等邮件传输的协议。 


    使用 UDP:当对网络通讯质量要求不高的时候,要求网络通讯速度能尽量的快,这时就可以使用 UDP。比如,日常生活中,常见使用 UDP 协议的应用如下:QQ 语音 QQ 视频


02

TCP协议实现

可靠传输的方式

方式概览




  • 应用数据被分割成 TCP 认为最适合发送的数据块。


  • TCP 给发送的每一个包进行编号,接收方对数据包进行排序,把有序数据传送给应用层。


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


  • TCP 的接收端会丢弃重复的数据。


  • 流量控制


  • 拥塞控制:当网络拥塞时,减少数据的发送。


  • ARQ 协议(自动重传请求):也是为了实现可靠传输的,它的基本原理就是每发完一个分组就停止发送,等待对方确认。在收到确认后再发下一个分组。


  • 超时重传:当 TCP 发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。


流量控制




    TCP 连接的每一方都有固定大小的缓冲空间,TCP 的接收端只允许发送端发送接收端缓冲区能接纳的数据。当接收方来不及处理发送方的数据,能提示发送方降低发送的速率,防止包丢失。TCP 使用的流量控制协议是可变大小的滑动窗口协议。(TCP 利用滑动窗口实现流量控制)


    在 TCP 协议当中窗口机制分为两种:


  • 固定的窗口大小

  • 滑动窗口


    固定窗口存在的问题:


  • 如果窗口过小,当传输比较大的数据的时候需要不停的对数据进行确认,这个时候就会造成很大的延迟。

  • 如果窗口过大,我们假设发送方一次发送 100 个数据,但接收方只能处理 50 个数据,这样每次都只对这 50 个数据进行确认。发送方下一次还是发送 100 个数据,但接受方还是只能处理 50 个数据。这样产生了不必要的数据来拥塞我们的链路。


    因此引入滑动窗口:本质上是描述接收方的 TCP 数据报缓冲区大小的数据,发送方根据这个数据来计算自己最多能发送多长的数据,如果发送方收到接收方的窗口大小为 0 的 TCP 数据报,那么发送方将停止发送数据,等到接收方发送窗口大小不为 0 的数据报的到来


拥塞控制




    计算机网络中的带宽、交换结点中的缓存及处理机等都是网络的资源。在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络的性能就会变坏,这种情况就叫做拥塞。拥塞控制就是防止过多的数据注入网络中,这样可以使网络中的路由器或链路不致过载。注意,拥塞控制和流量控制不同,前者是一个全局性的过程,而后者指点对点通信量的控制。拥塞控制的方法主要有以下四种:


  • 慢启动:不要一开始就发送大量的数据,先探测一下网络的拥塞程度,也就是说由小到大逐渐增加拥塞窗口的大小;


  • 拥塞避免:拥塞避免算法让拥塞窗口缓慢增长,即每经过一个往返时间 RTT 就把发送方的拥塞窗口 cwnd 加 1,而不是加倍,这样拥塞窗口按线性规律缓慢增长。


  • 快重传:快重传要求接收方在收到一个 失序的报文段 后就立即发出 重复确认(为的是使发送方及早知道有报文段没有到达对方)而不要等到自己发送数据时捎带确认。快重传算法规定,发送方只要一连收到三个重复确认就应当立即重传对方尚未收到的报文段,而不必继续等待设置的重传计时器时间到期。


  • 快恢复:快重传配合使用的还有快恢复算法,当发送方连续收到三个重复确认时,就执行 “乘法减小” 算法,把 ssthresh 门限减半,但是接下去并不执行慢开始算法:因为如果网络出现拥塞的话就不会收到好几个重复的确认,所以发送方现在认为网络可能没有出现拥塞。所以此时不执行慢开始算法,而是将 cwnd 设置为 ssthresh 的大小,然后执行拥塞避免算法。


【015】十分钟搞懂计算机网络TCP协议


ARQ协议




    自动重传请求(Automatic Repeat-reQuest,ARQ)是 OSI 模型中网络层和传输层的错误纠正协议之一。它通过使用确认和超时这两个机制,在不可靠服务的基础上实现可靠的信息传输。如果发送方在发送后一段时间之内没有收到确认帧,它通常会重新发送。ARQ 包括停止等待 ARQ 协议和连续 ARQ 协议。


    停止等待 ARQ 协议


    停止等待协议是为了实现可靠传输的,它的基本原理就是每发完一个分组就停止发送,等待对方确认(回复 ACK)。如果过了一段时间(超时时间后),还是没有收到 ACK 确认,说明没有发送成功,需要重新发送,直到收到确认后再发下一个分组;在停止等待协议中,若接收方收到重复分组,就丢弃该分组,但同时还要发送确认;


    连续 ARQ 协议


    连续 ARQ 协议可提高信道利用率。发送方维持一个发送窗口,凡位于发送窗口内的分组可以连续发送出去,而不需要等待对方确认。接收方一般采用累计确认,对按序到达的最后一个分组发送确认,表明到这个分组为止的所有分组都已经正确收到了。


03

TCP 三次握手和四次挥手


【015】十分钟搞懂计算机网络TCP协议


三次握手




三次握手:(我要和你建立链接,你真的要和我建立链接么,我真的要和你建立链接,成功)


  • 第一次握手:客户端发送 syn 包 (syn=x) 到服务器,并进入 SYN_SEND 状态,等待服务器确认;


  • 第二次握手:服务器收到 syn 包,必须确认客户的 ACK(ack=x+1),同时自己也发送一个 SYN 包(syn=y),即 SYN+ACK 包,此时服务器进入 SYN_RECV 状态;


  • 第三次握手:客户端收到服务器的 SYN+ACK 包,向服务器发送确认包 ACK (ack=y+1),此包发送完毕,客户端和服务器进入 ESTABLISHED 状态,完成三次握手。


    握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP 连接一旦建立,在通信双方中的任何一方主动关闭连接之前,TCP 连接都将被一直保持下去。


四次挥手




四次挥手:(我要和你断开链接;好的,断吧。我也要和你断开链接;好的,断吧)


  • 第一次挥手:客户端主动关闭方发送一个 FIN,用来关闭客户端到服务端的数据传送,也就是客户端告诉服务端:我已经不会再给你发数据了 (当然,在 fin 包之前发送出去的数据,如果没有收到对应的 ack 确认报文,客户端依然会重发这些数据),但是,此时客户端还可以接受数据。


  • 第二次挥手:服务端收到 FIN 包后,发送一个 ACK 给客户端,确认序号为收到序号 + 1(与 SYN 相同,一个 FIN 占用一个序号)。


  • 第三次挥手:服务端发送一个 FIN,用来关闭服务端到客户端的数据传送,也就是告诉客户端,我的数据也发送完了,不会再给你发数据了。


  • 第四次挥手:客户端收到 FIN 后,发送一个 ACK 给服务端,确认序号为收到序号 + 1,至此,完成四次挥手。


常见问题




    1.第 3 次握手失败会怎么办?


    第三次失败,只有客户端处于成功状态(因为第 2 次服务器返回了 ACK),服务器端没有接收到客户端的 ACK。


    这要分几种情况讨论:


  • 客户端发出的 ACK 丢失了,发出的 下一个数据包 没有丢失,则服务端接收到下一个数据包(这个数据包里也会带上 ACK 信息),能够进入正常的 ESTABLISHED 状态


  • 如果服务端和客户端都没有数据发送,或者服务端想发送数据(但是发不了,因为没有收到客户端的 ACK),服务器都会有定时器发送第二步 SYN+ACK 数据包,如果客户端再次发送 ACK 成功,建立连接。


  • 如果一直不成功,服务器肯定会有超时设置,超时之后会给客户端发 RTS 报文,进入 CLOSED 状态,防止 SYN 洪泛攻击。


    2.为什么 TCP 链接需要三次握手,两次不可以么,为什么?


    客户端发出的连接请求报文并未丢失,而是在某个网络节点长时间滞留了,以致延误到链接释放以后的某个时间才到达 Server。这是,Server 误以为这是 Client 发出的一个新的链接请求,于是就向客户端发送确认数据包,同意建立链接。若不采用 “三次握手”,那么只要 Server 发出确认数据包,新的链接就建立了。由于 client 此时并未发出建立链接的请求,所以其不会理睬 Server 的确认,也不与 Server 通信;而这时 Server 一直在等待 Client 的请求,这样 Server 就白白浪费了一定的资源。若采用 “三次握手”,在这种情况下,由于 Server 端没有收到来自客户端的确认,则就会知道 Client 并没有要求建立请求,就不会建立链接。


    3.为什么连接的时候是三次握手,关闭的时候却是四次握手?


    TCP 是全双工模式,关闭连接时,当主机 B 收到主机 A 的 FIN 报文时,仅仅表示主机 A 不再发送数据了但是还能接收数据。此时,主机 B 也未必全部数据都发送给 A 了,所以 B 可以立即 close;也可以发送一些数据给 A 后,再发送 FIN 报文给对方来表示同意现在关闭连接,因此,主机 BACK 和 FIN 一般都会分开发送。


1. TCP是如何保证可靠传输数据的?


2. TCP和UDP的区别?


3. TCP三次握手和四次挥手的过程?


4. TCP为什么需要三次握手?只进行两次会出现什么问题?第三次握手失败的情况TCP是如何处理的?


5. 为什么连接的时候是三次握手,关闭的时候却是四次握手?


获取详细答案。


【015】十分钟搞懂计算机网络TCP协议


THE

END


【015】十分钟搞懂计算机网络TCP协议

Java面试那点事