TCP和UDP面试总结

·  阅读 3174
TCP和UDP面试总结

把面试中遇到的点总结一下,问得太深的话,就没研究了。

TCP和UDP协议都是传输层协议。

1. TCP协议

TCP(Transmission Control Protocol,传输控制协议)是面向连接的协议。

  • 在收发数据前,必须和对方建立可靠的连接。

这个协议的重点是面向连接。他其中包含的内容都是和连接相关,首先介绍就是建立连接断开连接的过程。

1.1 建立连接:三次握手

三次握手的作用是:在进行通信前,确定客户端和服务端的收、发能力正常。

涉及的TCP报头

  • SYN
  • ACK:ACK序列为x+1表示之前的x数据都已经介绍,希望从x+1开始发送。
  • seq

1. 三次握手具体过程

  • 主机A向主机B发送含有同步序列号SYN的标志位的数据,
  • 主机B收到后,发送ACK和SYN给 主机A
  • 主机A收到后,发送应答ACK确认给 主机B 。

第一次握手:客户端发送包含SYN和seq的网络包,然后服务端收到了。

  • 服务端视角得出结论:客户端的发送能力、服务端的接收能力是正常的。

第二次握手:服务端发送包含SYN、ACK和seq的网络包,然后客户端收到了。

  • 客户端视角得出结论:服务端的接收、发送能力,客户端的接收、发送能力是正常的。

第三次握手:客户端发送包含ACK和seq的网络包,然后服务端收到了。

  • 服务端视角得出结论:客户端的接收、发送能力,服务端的发送、接收能力是正常的。

经历了上面的三次握手过程,客户端和服务端都确认了自己的接收、发送能力是正常的。之后就可以正常通信了。

2. 如果变成两次握手,是否可行

两次握手表示:客户端发送包含SYN的连接请求,服务端会回复ACK后就建立好连接了。

  1. 如客户端发出连接请求,但因连接请求报文丢失而未收到确认,于是客户端再重传一次连接请求。
  2. 后来收到了确认,建立了连接。
  3. 数据传输完毕后,就释放了连接。

过程1中,丢失的SYN报文段如果因为在某些网络结点长时间滞留了,延误到连接释放以后的某个时间才到达服务端。此时服务端误认为客户端又发出一次新的连接请求,于是就向客户端发出确认报文段,同意建立连接。这时候服务端认为建立了连接

  • 服务端保持连接一直等待客户端发送数据,浪费资源。

3. 三次握手失败出现的问题

服务端建立连接

  • 第三次的ACK在网络中丢失,那服务端该TCP连接的状态为SYN_RECV,并且会根据 TCP的超时重传机制,会等待3秒、6秒、12秒后重新发送SYN+ACK包,以便重新发送ACK包。 如果重发指定次数之后,仍然未收到客户端的ACK应答,那么一段时间后,服务端自动关闭这个连接。

客户端建立连接

  • 在linux c 中,client 一般是通过 connect() 函数来连接服务器的,而connect()是在 TCP的三次握手的第二次握手完成后就成功返回值。也就是说 client 在接收到 SYN+ACK包,它的TCP连接状态就为 established (已连接),表示该连接已经建立。那么如果 第三次握手中的ACK包丢失的情况下,Client 向 server端发送数据,Server端将以 RST包响应,方能感知到Server的错误。

syn洪泛攻击

  • 当第三次握手没有发送确认信息时,等待一段时间后,主机就会断开之前的半开连接并回收资源,这为dos(deny of service)攻击埋下隐患,当主动方主动发送大量的syn数据包,但并不做出第三次握手响应,server就会为这些syn包分配资源(但并未使用),就会使server占用大量内存,使server连接环境耗尽,这就是syn洪泛攻击。

1.2 断开连接:四次挥手

四次挥手可以分为两个部分,每个部分包含两次挥手,表示一个方向的连接断开。

客户端断开连接

  • 客户端发送包含FIN的网络包,服务端收到。
  • 服务端发送包含ACK的网络包(这里出现close-wait),客户端收到,此时这个方向上的连接关闭。

服务端断开连接

  • 服务端发送包含FIN的网络包,客户端收到。
  • 客户端发送包含ACK的网络包(time-wait开始计时),服务端收到,此时这个方向上的连接关闭。

1. time-wait的作用

time-wait开始的时间为tcp四次挥手中主动关闭连接方发送完最后一次挥手,也就是ACK=1的信号结束后,主动关闭连接方所处的状态。

time-wait的的持续时间为2MSL.

  • MSL是Maximum Segment Lifetime,译为报文最大生存时间,可为30s,1min或2min。工程上为2min,2msl就是4min。

:为什么要持续这么长的时间呢?

  1. 为了保证客户端发送的最后一个ack报文段能够到达服务器。因为这最后一个ack确认包可能会丢失,然后服务器就会超时重传第三次挥手的fin信息报,然后客户端再重传一次第四次挥手的ack报文。如果没有这2msl,客户端发送完最后一个ack数据报后直接关闭连接,那么就接收不到服务器超时重传的fin信息报(此处应该是客户端收到一个非法的报文段,而返回一个RST的数据报,表明拒绝此次通信,然后双方就产生异常,而不是收不到。),那么服务器就不能按正常步骤进入close状态。那么就会耗费服务器的资源。当网络中存在大量的timewait状态,那么服务器的压力可想而知。

  2. 在第四次挥手后,经过2msl的时间足以让本次连接产生的所有报文段都从网络中消失,这样下一次新的连接中就肯定不会出现旧连接的报文段了。已经失效的连接请求报文段出现在本次连接中。如果没有的话就可能这样:这次连接一挥手完马上就结束了,没有timewait。这次连接中有个迷失在网络中的syn包,然后下次连接又马上开始,下个连接发送syn包,迷失的syn包忽然又到达了对面,所以对面可能同时收到或者不同时间收到请求连接的syn包,然后就出现问题了。

2. close_wait

close_wait出现在被动关闭方

  • 出现close_wait只有一种情况,那就是对方发送一个FIN后,程序自己这边没有进一步发送ACK以确认。换句话说就是在对方关闭连接后,程序里没有检测到,或者程序里本身就已经忘了这个时候需要关闭连接,于是这个资源就一直被程序占用着。

这个时候快速的解决方法是:

  1. 关闭正在运行的程序,这个需要视业务情况而定。
  2. 尽快的修改程序里的bug,然后测试提交到线上服务器。

1.3 流量控制

流量控制:为了避免分组丢失,控制发送者的发送速度,使得接收者来得及接收。

  • 流量控制根本目的是防止分组丢失,它是构成TCP可靠性的一方面。

流量控制实现:由滑动窗口协议(连续ARQ协议)实现。滑动窗口协议既保证了分组无差错、有序接收,也实现了流量控制。

  • 主要的方式就是接收方返回的 ACK 中会包含自己的接收窗口的大小,并且利用大小来控制发送方的数据发送。

ACK序号:是期望接收到的下一字节的序号n,该n代表接收方已经接收到了前n-1字节数据,此时如果接收方收到第n+1字节数据而不是第n字节数据,接收方是不会发送序号为n+2的ACK的。

窗口大小: 当前的窗口大小m,如此发送方在接收到ACK包含的这两个数据后就可以计算出还可以发送多少字节的数据给对方,假定当前发送方已发送到第x字节,则可以发送的字节数就是y=m-(x-n).这就是滑动窗口控制流量的基本原理。

流量控制引发的死锁

情况:当发送者收到了一个窗口为0的应答,发送者便停止发送,等待接收者的下一个应答。但是如果这个窗口不为0的应答在传输过程丢失,发送者一直等待下去,而接收者以为发送者已经收到该应答,等待接收新数据,这样双方就相互等待,从而产生死锁。

解决:为了避免流量控制引发的死锁,TCP使用了持续计时器。每当发送者收到一个零窗口的应答后就启动该计时器。时间一到便主动发送报文询问接收者的窗口大小。若接收者仍然返回零窗口,则重置该计时器继续等待;若窗口不为0,则表示应答报文丢失了,此时重置发送窗口后开始发送,这样就避免了死锁的产生。

1.4 拥塞控制

拥塞控制:拥塞控制是作用于网络的,它是防止过多的数据注入到网络中,避免出现网络负载过大的情况。

发送方维持一个叫做拥塞窗口的状态变量。拥塞窗口的大小取决于网络的拥塞程度,并且动态地在变化。发送方让自己的发送窗口等于拥塞窗口,另外考虑到接受方的接收能力,发送窗口可能小于拥塞窗口。

常用的方法就是:

  1. 慢开始、拥塞避免
  2. 快重传、快恢复。

1. 慢开始、拥塞避免

慢开始:表示拥塞窗口从1开始,每过一个RTT,拥塞窗口加倍,直到窗口大小达到阈值。 拥塞避免: 达到阈值后,使用拥塞避免算法,每过一个RTT,增加1

  • 遇到网络拥塞后,阈值变为现在的一半,然后窗口重新从1开始

发生拥塞出现的表现:

  • 分组丢失(路由器缓存溢出)
  • 分组延迟过大(在路由器缓存中排队)

2. 快重传、快恢复

快重传:要求接收方在收到一个失序的报文段后就立即发出重复确认(为的是使发送方及早知道有报文段没有到达对方,可提高网络吞吐量约20%)而不要等到自己发送数据时捎带确认。

  • 快重传算法规定,发送方只要一连收到三个重复确认就应当立即重传对方尚未收到的报文段,而不必继续等待设置的重传计时器时间到期。

快恢复:当发送方连续收到三个重复确认时,就执行乘法减小算法,把拥塞窗口阈值减半(为了预防网络发生拥塞)。但是接下去并不执行慢开始算法,而是将当前发送的窗口设置为拥塞窗口阈值减半后的值,然后执行拥塞避免算法。

2. UDP协议

UDP协议:只在IP的数据报服务上增加了复用和分用的功能以及差错检测的功能。

  • 只有面向无连接的报文,不可靠传输的特点。
  • UDP对应用层交下来的数据只添加首部,并进行特别的处理,就交给网络层
  • 对网络层传递上来的用户数据报拆封首部后,原封不动的交给应用层。

3. TCP和UDP区别

1. 基于连接vs无连接

  • TCP是面向连接的协议。
  • UDP是无连接的协议。UDP更加适合消息的多播发布,从单个点向多个点传输消息。

2. 可靠性

  • TCP提供交付保证,传输过程中丢失,将会重发。
  • UDP是不可靠的,不提供任何交付保证。(网游和视频的丢包情况)

3. 有序性

  • TCP保证了消息的有序性,即使到达客户端顺序不同,TCP也会排序。
  • UDP不提供有序性保证。

4. 数据边界

  • TCP不保存数据边界。
    • 虽然TCP也将在收集所有字节之后生成一个完整的消息,但是这些信息在传给传输给接受端之前将储存在TCP缓冲区,以确保更好的使用网络带宽。
  • UDP保证。
    • 在UDP中,数据包单独发送的,只有当他们到达时,才会再次集成。包有明确的界限来哪些包已经收到,这意味着在消息发送后,在接收器接口将会有一个读操作,来生成一个完整的消息。

5. 速度

  • TCP速度慢
  • UDP速度快。应用在在线视频媒体,电视广播和多人在线游戏。

6. 发送消耗

  • TCP是重量级。
  • UDP是轻量级。
    • 因为UDP传输的信息中不承担任何间接创造连接,保证交货或秩序的的信息。
    • 这也反映在用于报头大小。

7. 报头大小

  • TCP头大。
    • 一个TCP数据包报头的大小是20字节。
    • TCP报头中包含序列号,ACK号,数据偏移量,保留,控制位,窗口,紧急指针,可选项,填充项,校验位,源端口和目的端口。
  • UDP头小。
    • UDP数据报报头是8个字节。
    • 而UDP报头只包含长度,源端口号,目的端口,和校验和。

8. 拥塞或流控制

  • TCP有流量控制。
    • 在任何用户数据可以被发送之前,TCP需要三数据包来设置一个套接字连接。TCP处理的可靠性和拥塞控制。
  • UDP不能进行流量控制。

9. 应用

  • 由于TCP提供可靠交付和有序性的保证,它是最适合需要高可靠并且对传输时间要求不高的应用。
  • UDP是更适合的应用程序需要快速,高效的传输的应用,如游戏。
  • UDP是无状态的性质,在服务器端需要对大量客户端产生的少量请求进行应答的应用中是非常有用的。
  • 在实践中,TCP被用于金融领域,如FIX协议是一种基于TCP的协议,而UDP是大量使用在游戏和娱乐场所。

10.上层使用的协议

  • 基于TCP协议的:Telnet,FTP以及SMTP协议。
  • 基于UDP协议的:DHCP、DNS、SNMP、TFTP、BOOTP。
分类:
后端
标签:
分类:
后端
标签:
收藏成功!
已添加到「」, 点击更改