banner
Hi my new friend!

tcp与udp

Scroll down

三次握手,四次挥手(TCP)

示意图

tcp连接建立断开示意图
tcp协议中内容,用于建立与断开连接.其中

  • 三次握手用于建立连接,保证客户端与服务端各自的收发能力
  • 四次挥手用于关闭连接,关闭双工连接

三次握手

  • 三次握手为什么能保证双方各自的收发能力?

第一次握手: 客户端向服务端发送SYN,如果服务端成功接收到,则服务端能确定客户端的发送能力、自己(服务端)的接收能力

在服务端接收完成后会在半连接队列中为SYN包开设一个条目,标识该连接处于Syn_RECV状态

第二次握手: 服务端给客户端发送Syn+Ack,如果客户端接收到,则客户端能确定自己(客户端)的发送能力和接受能力,能确定服务端的发送能力和接受能力.此时客户端进入Established状态
第三次握手: 客户端给服务端发送Ack,如果服务端接收到,则服务端能确定客户端的接收能力和自己的发送能力,此时服务端进入Established状态

在第三次握手后服务端将从半连接队列删除本次连接,将本次连接加入全连接队列

  • 为什么需要三次握手
  1. 三次握手能够保证双方各自的收发能力.
  2. 可以组织重复历史连接的初始化:
    客户端发给服务端的某个报文,因为网络原因留在了网络中,然后本次连接结束了,新连接开始了,这是旧报文又发到了服务端,服务端返回ack,然后客户端返回RST断开连接(第三次握手)。

    为什么客户端能识别出这是旧请求的ack:如果是最新请求的ack,则该ack的序列号应该是客户端最近生成的序列号+1.

  3. 可以同步双方的序列号
    第一次握手SYN客户端发送初始序列号,然后服务端第二次握手序列号+1,然后还需要保证这个序列号被客户端接收到了(第三次握手)
  4. 避免资源的浪费

四次挥手

四次挥手示意图

  • 一定是四次挥手嘛?
    不一定.第二次挥手和第三次挥手可能合并,当服务端接收到第一次挥手的SYN后,如果服务端->客户端的方向上没有数据要发送时,第二次和第三次挥手可以合并为一次.

  • 如果连接中,服务器挂了,客户端会断开连接吗

  1. 当服务器挂了指的是进程崩溃时,内核会向客户端发送FIN,完成四次挥手
  2. 当服务器挂了指的是服务器宕机时:
  • 如果客户端向服务器发送了请求,会失败,则会引起重试机制,当最远重试间隔达到某一阈值时,客户端会关闭连接

  • 如果客户端未向服务器发送请求,这时取决于客户端的keepAlive设置
    如果开启了keepAlive机制,客户端会定时向服务器发送检测报文,如果发现服务器掉线则断开连接
    如果没有开启keepAlive机制,就会保持连接直至发送请求

  • 讲讲拥塞控制
    拥塞控制是防止过多的数据进入到网络层,造成过负载.是针对全局而言的

  1. 慢开始算法
    cwnd从1开始逐渐翻倍,网络阻塞时重置为1
  2. 拥塞避免算法
    cwnd达到ssthresh后,cwnd的增长方式不再是翻倍,而是+1,当网络阻塞时就爱那个ssthresh/2,cwnd重置为1
  3. 快重传算法
    当客户端发现没有接收到某个报文时,传回三个ACK,然后服务端马上重传丢失的报文而不用等待定时器超时
  4. 快恢复算法
    一般与快重传算法一起.当收到三个ACK后(说明网络情况没那么糟糕)
    1
    2
    cwnd=cwnd/2
    ssthresh = cwnd
    即窗口和慢开始上限均变为窗口大小的一半
  • timewait是多久
    2MSL

  • 为什么要有timewait

  1. 处理延时的报文,防止对后续连接有影响

    并不能保证完全处理掉延时的报文,如果要完全处理应该考虑对方的重传次数,最大超时重传时间,MSL,远不止2MSL

  2. 保证被动关闭方收到了自己的ack
    TIME_WAIT至少需要持续2MSL时长,这2个MSL中的第一个MSL是为了等自己发出去的最后一个ACK从网络中消失,而第二MSL是为了等在对端收到ACK之前的一刹那可能重传的FIN报文从网络中消失。
  • timewait的坏处
    连接处于timewait状态时,该端口已经不再进行实际的通信,但是端口号没有释放,占用着端口号
    高并发环境下,可能造成大量的端口号处于timewait状态,占用着端口资源
    另外大量的timewait也会占用内存,cpu资源(当然这不是主要的坏处)

  • 如何解决大量的timewait

  1. 修改系统内核参数
    1
    2
    3
    net.ipv4.tcp.tw.reuse = 1  //表示可重用timewait的端口
    net.ipv4.tcp.tw.recycle = 1 //表示快速回收timewait端口
    ....
  2. 将短连接改为长连接

TCP,UDP区别

  1. Tcp面向连接,UDP无连接
  2. TCP可靠,UDP不可靠
  3. TCP具有重传机制(还有Ack机制),保证有序,Udp没有且无序
  4. tcp对系统资源要求多,相对慢;udp更快
  5. tcp有流量控制和拥塞控制的能力
  • TCP,udp各自应用场景
    TCP: web浏览,文件传输,邮件…
    UDP: 视频与直播流媒体, 网络游戏…

  • tcp是长连接还是短连接
    tcp既有长连接,也有短连接

    短连接: 每次请求都会新建,断开连接;方便管理(连接的都是有用的)但是频繁地新建断开浪费cpu资源
    长连接: 请求完可以不断开连接;不方便管理(连接的都是有用的)但无需频繁地新建断开

  • 什么是tcp粘包
    接收方接收到的某一个数据包中包含多个数据包(包括数据包发生拆包形成的小数据包)
    解决方案:

  1. 为数据包头部添加数据包长度
  2. 为数据包之间添加特殊的分隔符
  3. 设置数据包长度为固定值,如果不够则用指定字符凑
  • 怎么实现udp的可靠性
    现在已经有了较成熟的udp可靠性方案: QUIC协议
  1. 如何实现可靠性的
    QUIC也有重试机制,并且与tcp不同的是QUIC的序列号(Packet Header中的Packet Number)是递增的(tcp重传序列号是不变)
    通过FrameHeader来保证顺序性,以Stream这种Frame类型为例,通过其中的StreamId和offset保证数据的有序性
    优点:
    可以解决tcp重传rtt歧义的问题(即接收到重传的数据,怎么知道是第一次发的还是哪次重传发的,导致rtt计算不准确)
    可以乱序确认,即使某个序列号的数据没收到,也可以继续往下确认
  • quic如何解决队头堵塞问题
    tcp通过抽象Stream来实现请求的并发,但是共用的tcp窗口,如果一个stream丢包了,会把后面所有的stream都阻塞
    quic为每一个steam分配一个独立的滑动窗口,即使一个Strean异常了,也不会阻塞其他的stream
其他文章
目录导航 置顶
  1. 1. 三次握手,四次挥手(TCP)
    1. 1.1. 示意图
    2. 1.2. 三次握手
    3. 1.3. 四次挥手
  2. 2. TCP,UDP区别