面试遇到TCP,读完这篇就够了!

本文首发于微信公众号:聊点技术,原文标题《 面试遇到TCP,读完这篇就够了!

1. 概述

传输层为相互通信的应用进程提供逻辑通信服务,属于面向通信部分的最高层,同时也是用户功能的最底层,运输层还要对收到的报文进行差错检测。应用层中不同进程的报文通过不同端口向下交到运输层。将应用进程之间的通信称为端到端的通信。

传输层向高层屏蔽了下面网络的核心细节,使应用程序看起来像是在两个传输层实体之间有一条端到端的逻辑通信信道。

传输层有两种运输协议:面向连接的TCP、无连接的UDP

2. 传输层的复用与分用

复用指发送方不同进程都可以通过同一个传输层协议传送数据。分用指接收方的运输层在剥去报文的首部后能把这些数据正确的交付到目的应用进程。

3. UDP和TCP的特点

  • UDP是无连接的,尽最大可能交付,无拥塞控制,面向报文(对应用层传下来的报文不合并也不拆分只添加UDP首部),支持一对一、一对多、多对一和多对多的交互通信,首部开销小(只有20个字节)。UDP传送的数据单位是UDP用户数据报。
  • TCP是面向连接的,提供可靠交付,有流量控制,拥塞控制,提供全双工通信,面向字节流(把应用层传下来的报文看成字节流,把字节流组织成大小不等的数据块),每一条TCP连接只能是点对点的(一对一),不提供广播和多播服务。TCP传送的数据单位是TCP报文段。
    在这里插入图片描述

4. 传输控制协议TCP

TCP的面向连接是指在进行通信前需要在两端做好通信的准备工作。
端口号和IP地址拼接起来构成了套接字,TCP连接的端点是套接字。

套接字 socket = (IP地址 : 端口号)

两个套接字能够确定一条唯一的TCP连接,即:

TCP连接 ::= {socket1, socket2}
          = {(IP1: port1), (IP2: port2)}

在这里插入图片描述
序号:对字节流编号,如序号为401表示第一个字节的编号为401,若携带200字节数据,则下一报文段的序号应为601。

数据偏移:指TCP数据部分距离报文段起始处的偏移量,实际指首部长度。首部最长60字节,最短20字节。数据偏移占4位,值为1时代表首部长度为4字节。,由于首部长度最少为20字节,因此该值最小为5。

确认号:期望收到的下一个报文段的第一个数据字节的序号。

确认ACK:当ACK=1时确认号字段有效,否则无效。TCP 规定,在连接建立后所有传送的报文段都必须把ACK置1。

同步SYN:在连接建立时用来同步序号。当SYN=1,ACK=0时表示这是一个连接请求报文段。若对方同意建立连接,则响应报文中SYN=1,ACK=1。

终止FIN:用来释放一个连接,当FIN=1时表示此报文段的发送方的数据已发送完毕,并要求释放连接。

窗口:作为接收方让发送方设置其发送窗口的依据。因接收方缓存空间有限。

复位RST:当RST=1时表明TCP连接中出现差错,必须释放连接,然后重新建立连接。

无报文长度字段,使用TCP时,不必关心数据报大小“流协议”。

最大报文段长度MSS是每一个TCP报文段中的数据字段的最大长度。数据字段加上TCP首部等于整个TCP报文段。MSS应尽可能大些,只要在IP层传输时不需要再进行分片就行。默认MSS大小536字节。

TCP规定,SYN报文段(SYN=1的报文段)不能携带数据,但要消耗掉一个序号。ACK报文段可以携带数据,如果不携带数据则不消耗序号。

5.TCP的三次握手

在这里插入图片描述
TCP连接有三个阶段,分别是:建立连接、数据传送和释放连接。

如上图所示,A为客户端,B为服务端。

  • 首先B处于监听状态(LISTEN),等待客户端的连接请求。

  • A向B发送连接请求报文,其中报文首部中的SYN=1,ACK=0,选择一个初始的序号seq=x

  • B收到连接请求报文后,如果同意建立连接,则向A发送连接确认报文,报文首部中SYN=1、ACK=1、确认号为x+1,同时也选择一个初始的序号seq=y

  • A收到B的连接确认报文后,还要向B发出确认,确认号为y+1,序号为x+1。

  • B收到A的确认后,连接建立。

6. 第三次握手的原因

谢希仁的计算机网络中提到,第三次确认是为了防止已经失效的客户端连接请求报文段突然又传输到了服务器1
客户端发送的连接请求如果在网络中滞留,则需要很长时间才能收到服务器端发回的连接确认。客户端等待一个超时重传时间之后,就会重新请求连接。但是这个滞留的连接请求最后还是会到达服务器,如果不进行三次握手,那么服务器就会打开两个连接。如果有第三次握手,客户端会忽略服务器之后发送的对滞留连接请求的连接确认,不进行第三次握手,因此就不会再次打开连接。
图解TCP_IP2中提到,如上图中所示,TCP在数据通信前通过TCP首部发送一个SYN包作为建立连接的请求等待确认应答。如果对端发来确认应答,则认为可以进行数据通信。如果对端的确认应答未能到达,就不会进行数据通信。由于通信是全双工的,参与通信的两端需要分别建立自己的连接。

7.四次挥手释放连接

在这里插入图片描述

  • A发送连接释放报文,FIN=1。此时A进入FIN_WAIT_1(终止等待1)状态。
  • B收到连接释放报文后发出确认,此时TCP属于半关闭状态,B能向A发送数据但A不能向B发送数据。B进入CLOSE_WAIT(关闭等待)状态。A收到B的确认后,进入FIN_WAIT_2(终止等待2)状态。
  • 当B不再需要连接时,发送连接释放报文,FIN=1。
  • A收到后发出确认,A进入TIME_WAIT状态,等待2MSL(最大报文存活时间)后释放连接。A进入CLOSED状态。
  • B收到A的确认后释放连接。

同样由于通信是全双工的,参与通信的两方需要单独释放连接。

8. 存在TIME-WAIT的原因

客户端接收到服务器端的FIN报文后进入此状态(执行主动关闭的那端经历了这个状态),还需要等待2MSL才进入CLOSED状态。MSL是最长分节生命期。TIME_WAIT状态存在的理由:

  • 确保最后一个确认报文能够到达,可靠的实现TCP全双工连接的终止。如果B没收到A发送来的确认报文,那么就会重新发送连接释放请求报文,A等待一段时间就是为了处理这种情况的发生(处理最终那个ACK丢失的情况)。
  • 等待一段时间是为了让本连接持续时间内所产生的所有报文都从网络中消失,使得下一个新的连接不会出现旧的连接请求报文。如果在关闭连接之后很快又使用相同的IP和端口建立新的连接,必须防止某个连接的老的报文在连接已终止后再现,从而被误解成新连接的报文。2 MSL确保新连接建立前老的分组都已在网络中消逝。

9. TCP的有限状态机

TCP有限状态机图中每个方框表示TCP可能存在的状态,方框中内是TCP连接状态名,状态之间的箭头表示可能发生的状态变迁。箭头旁边的字指明了引起变迁的原因。图中,蓝色粗实线箭头表示客户端进程的状态变迁,蓝色粗虚线箭头表示服务端进程的状态变迁,细线箭头表示异常变迁。
CLOSING状态:客户端和服务端同时发送FIN。客户端发起关闭请求,发送FIN之后等待服务器端回应ACK,此时服务器端同时也发送FIN发起关闭请求,并且被客户端先于ACK接收到。
CLOSE-WAIT:接收到FIN之后,被动关闭的一方进入此状态。
FIN-WAIT-1:第一次挥手。主动关闭的一方(执行主动关闭的一方既可以是客户端,也可以是服务器端,这里以客户端执行主动关闭为例)终止连接时,发送FIN给对方,然后等待对方返回确认。
FIN-WAIT-2:主动关闭的一方先执行主动关闭发送FIN,然后接收到被动方返回的确认后进入此状态。
在这里插入图片描述

10. 滑动窗口

TCP的滑动窗口以字节为单位,窗口是缓存的一部分,用来暂时存放字节流。发送端的发送窗口表示:在没有收到接收端的确认的情况下,发送端可以连续把窗口内的数据都发送出去。凡是已经发送过的数据,在未收到确认之前都必须暂时保留,以便在超时重传时使用。只有接收窗口向前滑动并发送了确认时,发送窗口才能向前滑动。

滑动窗口主要步骤如下:

  • 发送端和接收端分别设定发送窗口和接收窗口。
  • 三次握手时,客户端把自己的缓冲区大小即窗口大小发送给服务器,服务器回应时也将窗口大小发送给客户端,两者都知道了彼此的窗口大小。
  • 若发送端的发送窗口大小为20,发送端可以向接收端发送20个字节的数据,如果接收端的缓冲区满了,发送端需等待收到接收端对已发送数据的确认才能继续发送数据。
  • 如果接收端的缓冲区中有1个字节被读取,接收端会回复ACK给发送端,接收窗口向前滑动,报文中窗口大小为1,就说明发送端还可发送1个字节的数据,发送窗口向前滑动,之后等待接收端的确认报文。
    在这里插入图片描述

描述一个发送窗口的状态需要三个指针:P1,P2和P3。小于P1的是已经发送并已收到确认的部分,大于P3的是不允许发送的部分。

P3-P1=A的发送窗口;

P2-P1=已发送但尚未收到确认的字节数;

P3-P2=允许发送但当前尚未发送的字节数。

图中B收到了序号为32和33的数据,而31的没有收到,未按序到达。此时,B只能对按序收到的数据中的最高序号给出确认,因此B发送的确认报文段中的序号仍然是31(即期望收到的序号)。当接收方收到乱序片段时,需重复发送最近一次确认的有序的报文段的ACK。

11. 停止等待协议&ARQ

停止等待是指每发送完一个分组后,就停止发送,暂时保留已发送的分组副本,等待对方确认,等收到确认后再发送下一个分组。当发送窗口和接收窗口都为1时,就是停止等待协议。如果计时超时,发送端就认为分组丢失或被破坏,需要重新发送。
通过确认和重传机制,可以在不可靠的传输网络上实现可靠的通信。
连续ARQ协议可提高信道利用率。发送维持发送窗口,凡位于发送窗口内的分组可连续发送出去,而不需等待对方确认。接收方采用累积确认,对按序到达的最后一个分组发送确认,表明到这个分组位置的所有分组都已经正确收到了。

12. 超时重传

TCP记录每个报文段的发出时间,以及收到确认的时间。这两个时间差是报文段的往返时间(RTT)。超时重传指发送的报文段在规定时间内没有收到确认,就要重新发送这一报文段。

13. 流量控制

流量控制是为了控制发送方发送速率,保证接收方来得及接收,同时不要使网络发生堵塞。
利用滑动窗口机制实现流量控制,发送方的发送窗口不能超过接收方给出的接收窗口的数值。接收方发送的确认报文中的窗口字段可以用来控制发送方窗口大小,从而影响发送方的发送速率。将窗口字段设置为0,则发送方不能发送数据。

14. 拥塞控制

拥塞控制是一个全局性的过程,涉及到所有的主机,所有的路由器,以及与降低网络传输性能有关的所有因素。TCP主要通过四个算法来进行拥塞控制:慢开始、拥塞避免、快重传、快恢复。

如果网络出现拥塞,分组将会丢失,此时发送方会继续重传,从而导致网络拥塞程度更高。因此当出现拥塞时,应当控制发送方的速率。流量控制是为了让接收方能来得及接收,而拥塞控制是为了降低整个网络的拥塞程度。
在这里插入图片描述
发送方需要维护一个叫做拥塞窗口(cwnd)的状态变量,拥塞窗口是一个状态变量,实际决定发送方能发送多少数据的是发送方窗口。

发送窗口 = min(接收窗口,拥塞窗口)

发送方的发送窗口一定是不能大于接收方的接收窗口的!
为了便于讨论,假设:接收方有足够大的接收缓存,因此不会发生流量控制;虽然TCP的窗口基于字节,但这里设窗口的大小单位为报文段。

慢开始与拥塞避免

发送的最初执行慢开始,令cwnd=1进行试探,发送方只能发送1个报文段;当收到确认后,将cwnd加倍,因此之后发送方能够发送的报文段数量为:2、4、8、16等。慢开始过程中,拥塞窗口的大小呈指数增长,这会让cwnd增长速度过快,使得网络拥塞的可能性更高。因此设置了一个慢开始门限ssthresh,当cwnd≥ssthresh时,进入拥塞避免,每个轮次只将cwnd加1。当某个传输轮次中的报文段出现了超时,则令ssthresh=cwnd/2(慢开始门限=当前拥塞窗口的一半),然后重新执行慢开始(cwnd从1开始)。
在这里插入图片描述

快重传与快恢复

在接收方,每次接收到报文段都应该对最后一个已收到的有序报文段进行确认。如已经接收到M1和M2,此时收到M4,应当发送对M2的确认。在发送方,如果收到三个重复确认,那么可以知道下一个报文段丢失,此时执行快重传,立即重传下一个报文段。例如收到三个M2的确认,则说明M3丢失,则发送端需要立即重传M3,在这种情况下,只是丢失个别报文段,而不是网络拥塞。因此执行快恢复,令ssthresh =cwnd/2,cwnd=ssthresh,此时直接进入拥塞避免。
在这里插入图片描述

15. 面向报文的UDP

UDP的面向报文意味着对应用层传下来的报文,既不合并也不拆分,保留报文的边界。即,应用层交给UDP多长的报文,UDP就照样发送,即一次发送一个报文。因此,应用程序必须选择合适大小的报文,若报文太长,UDP把它交给IP层后,IP层在传送时可能要进行分片,会降低IP层的效率。
UDP首部格式
UDP首部字段有四个字段(8字节),包括源端口、目的端口、长度、检验和。12字节的伪首部是为了计算检验和临时添加的。
发送方计算检验和:首先把全零放入检验和字段,再添加伪首部。若UDP用户数据报的数据部分不是偶数个字节,则填入一个全零字节(不发送)。求出检验和后填入到检验和字段。
UDP不保证数据报会到达其最终目的地,不保证各个数据报的先后顺序跨网络后会保持不变,也不保证每个数据报只到达一次。UDP在传送数据前不需要先建立连接,对方收到UDP报文后也不许给出任何确认。UDP提供无连接服务,UDP客户端与服务器不必存在任何长期的关系。UDP客户端可以创建一个套接字并发送数据报给服务器,然后立即用同一套接字发送另一个数据报给另一个服务器。一个UDP服务器可以用同一个套接字从若干个不同的客户接收数据报。

本文首发于微信公众号:聊点技术,原文标题《 面试遇到TCP,读完这篇就够了!

在这里插入图片描述


  1. 谢希仁. 计算机网络(第七版) [M]. 北京: 电子工业出版社, 2017. ↩︎

  2. 竹下隆史, 乌尼日其其格. 图解TCP/IP(第5版)[M]. 北京:人民邮电出版社, 2013. ↩︎

  • 9
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值