区别:
    TCP:基于连接,相当于打电话,从电话接通到互相通话到结束挂断,这一系列都有及时的反馈
    UDP:基于非连接,相当于写信,信寄出去后对方是否收到,信的内容是否完整,顺序是否正确,收信人的地址,收信人是否存在都无法确认

    TCP三次握手
    三次握手是建立连接的过程,当客户端想服务端发起连接时,会先发一包连接请求数据,询问是否能建立连接,这个数据包称为SYN包。如果服务端同意连接,会回复SYN+ACK包,客户端收到之后回复一个ACK包,连接建立。
    为什么要三次握手而不是两次握手
    假设采用两次握手建立连接,客户端向服务端发送了一个SYN包来请求建立连接,因为某些未知的原因并没有到达服务器,在中间的某个网络节点产生了滞留。为了建立连接客户端会重发SYN包,这次数据包正常送达,服务端回复SYN+ACK包之后建立连接。但是第一包阻塞的网络节点突然恢复,第一包SYN包又送达到服务端。这时候服务端会认为是客户端又发起了一个新的连接,从而等待客户端数据状态。服务端认为是两次连接,而客户端认为是一个连接,造成了状态不一致。
    如果是三次握手下,服务端收不到最后的ACK包,自然不会认为连接建立成功。所以三次握手就是为了解决网络信道不可靠的问题。

    TCP协议需要在不可靠的信道上保证可靠的连接,但现在有几个问题:

    • 一包数据有可能被拆成多包发送,如何处理丢包问题
    • 这些数据包到达的先后顺序不同,如何处理乱序问题

    针对这些问题,TCP为每个连接建立了发送缓冲区,对被分段的每个数据包标上序列号,从0开始依次加1。发送数据时从发送缓冲区取一部分数据组成发送报文,在TCP协议头部会加入序列号和长度的信息(数据包向下经过每一层都会在头部加上该层的一些信息)。
    接收端在收到数据后会回复确认报文,确认报文中的ACK=接收序列号+长度,也就是告诉发送端下一包数据的起始序列号。这样一问一答的发送方式,能够使发送端确认发送的数据已经被对方收到,发送端也可以一次发送连续的多包数据,接收端只需要回复一次ACK就可以了。接收端最后根据序列号和长度重构出来完整的数据。
    假设其中丢失了某些数据包,在接收端可以要求发送端重传。

    四次挥手
    处于连接状态的客户端和服务端都可以发起关闭连接请求。
    假设客户端主动发起连接关闭请求,他需要向服务端发起一包FIN包,表示要关闭连接,自己进入终止等待1状态。服务端收到FIN包,发送一包ACK包,表示自己进入了关闭等待状态,而客户端进入终止等待2状态。服务端此时还可以发送未发送的数据,而客户端还可以接受数据。待服务端发送完数据之后发送一包FIN包,进入最后确认状态。客户端收到之后回复ACK包,进入超时等待状态,经过超时时间后关闭连接。而服务端收到ACK包后立即关闭连接。

    为什么客户端需要等待超时时间?
    这是为了保证对方已收到ACK包。因为假设客户端发送完最后一包ACK包就释放了连接,一旦ACK包在网络中丢失,服务端将一直停留在最后确认状态。如果客户端发送最后一包ACK包后等待一段时间,这时服务端因为没有收到ACK包会重发FIN包,客户端会响应这个FIN包并重发ACK包并刷新超时时间。这个机制跟三次握手一样,也是为了在不可靠的网络链路中进行可靠的连接断开确认。

    UDP协议
    UDP协议是基于非连接的,发送数据包就是简单的把数据包封装一下,然后从网卡发出去就可以了,数据包之间并没有状态上的联系。
    正因为UDP这种简单的处理方式,导致他的性能损耗非常少,资源占用少。但对于网络传输过程中的产生的丢包,UDP协议并不能保证。所以UDP在传输稳定性上要弱于TCP。
    UDP适用于对实时性要求较高,但是对少量丢包并没有太大要求的场景。比如域名查询、语音通话、视频直播等。

    image.png