首先补充几个基本知识:
a、SYN表示建立连接
b、FIN表示关闭连接
c、ACK表示进行响应
d、PSH表示有数据进行传输
e、PST表示连接重置
TCP的三次挥手
客户端向服务端申请建立连接时:
1、客户端向服务端发送SYN包(第一次握手)
2、服务端向客户端发送SYN+ACK包(第二次握手)
3、客户端向服务端发送ACK包(第三次握手)
建立连接!
那么为什么要三次握手呢?
按照我们的思维,设想在广大人群中A想要找到B,只需要A:B你在哪?(第一次握手)然后B:A我在这!(第二次握手)这样A和B就已经可以建立连接了。
但是在TCP数据传输中,数据的传输会受到通道稳定性的影响。例如我们第一次客户端向服务端发送SYN包(称SYN1)后由于网络不稳定导致服务端发生滞留,之后客户端又发送了一次请求,向服务端发送SYN包(称SYN2)并且服务端收到了,此时SYN1也送达了服务端,这时分别从客户端和服务端来看,客户端发送了一个请求,而服务端却收到两个请求,造成状态不一致。这也是为什么需要三次握手的原因。
第三次握手,由于SYN1对客户端来说是已经失效的东西(已经通过SYN2建立新的连接,不再需要),那么客户端不会发送SYN1的ACK包,则此连接不会建立,解决了上述问题。
从本质上来说,TCP是为了解决网络传输通道不稳定的问题!
TCP的四次挥手
客户端(服务端)向服务端(客户端)申请取消连接:
1、客户端向服务端发送FIN包,表示要关闭连接,客户端端进入终止等待1状态(第一次挥手)
2、服务端向客户端发送ACK包,服务端进入关闭等待状态,客户端进入终止等待2状态(第二次挥手)
【此时客户端仍可以发送数据,服务端仍可以接收数据】
3、服务端向客户端发送FIN包,最后确认是否关闭连接(第三次挥手)
4、客户端向服务端发送ACK包,进入超时等待状态,经过超时时间关闭连接,服务端收到ACK包后立即关闭(第四次握手)
为什么设置超时等待时间?
保证对方收到最后一个ACK包,如果客户端发送ACK包后ACK包丢失了那么服务端一直处于最后确认状态,占用资源;服务端没有收到ACK包会重发FIN包(也是为了解决网络通信通道不稳定问题,避免丢包)【也就是说关闭连接分为两个阶段,1-是否要关闭连接,2-是否确认关闭连接】
补充
TCP丢包和乱序问题
为了解决上述问题,TCP协议采用了缓冲区的方式,发送的时候从缓冲区(每个字节有一个序列哈,序列号从0开始)截取一部分数据组成发送报文,发送报文有序列号和长度,而服务端则需要回复确认报文ACK=序列号+长度(下次发送数据的开始序列号)
客户端将数据分割成碎片发送给服务端,服务端根据序列号和长度再进行恢复就可以得到完整有序的数据,有丢失的数据可以进行重传,ACK=丢失的开始序列号(数据传输是双向的,可以客户端向服务端传输,反之也成立)
TCP和UDP的区别
TCP是先建立连接再进行数据传输;UDP是根据地址直接把数据发送出去
拿我们人想要相互交流举例:
TCP:A和B通过打电话的方式进行交流,先把电话打通再进行交流
UDP:A和B通过写信的方式交流,根据地址直接把信寄出去,中途很可能信丢了
TCP由于一直建立连接占用资源,性能损耗多,资源占用多但传输稳定性强而UDP则相反且速度更快。