回顾TCP/UDP
首先回顾一下TCP与UDP,我们常用的网络通讯,比如浏览网页、软件聊天、和你每天刷的视频、都是通过这两种协议进行传输的。
他们工作在传输层,目标都是在程序之间传输数据,数据可以是文本文件也可以是视频,也可以是图片,对于TCP和UDP来说都是一堆二进制数,并没有多大的区别。
他俩的最大区别就是TCP建立了连接,而UDP没有建立连接。
举一个例子:
我们排除速度因素,写信与打电话的区别,就是当我们写完的信寄出去时,我们不能保证对方是否能收到,收到的信是否完整,先后寄出两封信时,是否按照顺序到达,甚至填写的收信人和收信地址都无法确认。
而打电话则不同,互相通话再到结束通话后挂断,这一系列的流程都能得到及时的反馈,并且能确认对方准确的接收到。打电话是基于连接的,也就是TCP。而写信就是基于非连接的也就是UDP。
那么TCP是如何保障以上过程的呢?
有三个关键步骤:分别是三次握手、传输确认、四次挥手
三次握手:
1.当客户端向服务端发起连接的时,会先发一包连接请求数据(SYN包),过去询问一下能否与你建立连接。
2.如果对方同意连接就会回复一包 SYN+ACK包
3.客户端收到之后回复一包 ACK包,连接建立。
为什么是三次握手而不是两次握手?
服务端回复完SYN+ACK之后就建立连接,这是为了防止因为已失效的请求报文突然又传到服务器引起的错误。
四次挥手:
处于连接状态的客户端和服务端都可以发起关闭连接请求,此时需要四次挥手进行连接关闭。
1.假设客户端主动向服务端发起连接请求,需要向服务端发起一个 FIN包,表示关闭连接,自己进入终止等待1状态。这是第一次挥手。
2.服务端收到 FIN包后,回复一包 ACK包,表示自进入关闭等待状态,客户端进入终止等待二状态,这是第二次挥手。服务端还可以发送未发送的数据,而客户端还可以接收数据。
3.待服务端发送完数据之后,发送一包 FIN包,进入最后确认状态,这是第三次挥手。
4.客户端收到之后回复 ACK包,进入超时等待状态,经过超时时间后关闭连接,而服务端收到 ACK包后立即关闭连接,这是第四次挥手。
为什么客户端需要等待超时时间?
这是为了保证对方已收到ACK包。
因为假设客户端发送完最后一包ACK包后就释放了连接,一旦 ACK 包在网络中丢失,服务端将一直停留在最后确认状态,如果客户端发送最后一包ACK包后,等待一段时间,这时服务端因为没有收到ACK包,就会重新发送 FIN包,客户端会响应这个FIN包并且重发ACK包并刷新超时时间。