三次握手:
例如我们打电话的时候先要确认双方身份。
假设客户端是儿子,服务端是妈妈
儿子:喂,妈妈在吗?
妈妈:我在,是儿子给我打电话吗?
儿子:对,是我啊,可以聊了。
如果双方确认不了身份就挂机不聊了。
TCP协议包每种标识对应的含义
* SYN(synchronous),建立联机。
* ACK(acknowledgement),确认。
* PSH(push),传输。
* FIN(finish),结束。
* RST(reset),重置。
* URG(urgent),紧急。
3次握手的过程:
1 client 发送 SYN seq=x 请求与服务器建立连接
2 server 发送 ACK=x+1,SYN seq=y 确认请求,请求与客户端建立连接
3 client 发送 ACK=y+1 确认请求
确认请求的方式就是把syn里面的x的值加1。
注意!!TCP协议每次传输数据包前面都会先再带一个ACK确认包,告诉对方我已经收到上次的数据包了;这也是TCP和UDP最大的区别。
TCP如果没有收到确认包,就会隔一段时间再发送一次数据,来保证每次传输的数据都是完整的。而UDP中没有,所以TCP稳定。
为什么要进行3次握手,因为客户端在没有收到响应的情况下会因为连接超时从而断开连接,服务端为了不浪费资源,发现客户端超时之后就会关闭连接了。
四次挥手:
三次握手是为了建立连接,而四次挥手是为了关闭连接,如果理解三次握手,那么四次挥手就非常好理解了,原理差不多。
先看两张图
1 客户端先发送关闭请求包FIN,进入等待状态1
2 服务端收到关闭且请求后,先发送确认收到的包ACK,进入关闭等待状态。这时候客户端先收到了确认包,进入等待状态2.
3 服务端也发送一个请求关闭的包FIN,进入最后确认状态
4 客户端收到服务端的关闭请求后发送最终确认包ACK给服务端,然后进入等待计时器,在计时器结束后,进入关闭状态,服务端收到最终确认包之后立即进入关闭状态。
为何要四次分手呢?
1 当客户端发出FIN报文段时,只是表示已经没有数据要发送了。但是,这个时候主客户端还是可以接受来自服务器的数据;
2 当服务器返回ACK报文段时,表示它已经知道客户端没有数据发送了,但是还是可以往客户端推送数据包;
3 当服务器也发送了FIN报文段时,就会告诉客户端,我也没有数据要发送了;
4 再双方都确认之后彼此就会愉快的中断这次TCP连接。
如果要正确的理解四次分手的原理,就需要了解四次分手过程中的状态变化。
FIN_WAIT_1: 这个状态要好好解释一下,其实FIN_WAIT_1和FIN_WAIT_2状态的真正含义都是表示等待对方的FIN报文。而这两种状态的区别是:FIN_WAIT_1状态实际上是当SOCKET在ESTABLISHED状态时,它想主动关闭连接,向对方发送了FIN报文,此时该SOCKET即进入到FIN_WAIT_1状态。而当对方回应ACK报文后,则进入到FIN_WAIT_2状态,当然在实际的正常情况下,无论对方何种情况下,都应该马上回应ACK报文,所以FIN_WAIT_1状态一般是比较难见到的,而FIN_WAIT_2状态还有时常常可以用netstat看到。(主动方)
FIN_WAIT_2:上面已经详细解释了这种状态,实际上FIN_WAIT_2状态下的SOCKET,表示半连接,也即有一方要求close连接,但另外还告诉对方,我暂时还有点数据需要传送给你(ACK信息),稍后再关闭连接。(主动方)
CLOSE_WAIT:这种状态的含义其实是表示在等待关闭。怎么理解呢?当对方close一个SOCKET后发送FIN报文给自己,你系统毫无疑问地会回应一个ACK报文给对方,此时则进入到CLOSE_WAIT状态。接下来呢,实际上你真正需要考虑的事情是察看你是否还有数据发送给对方,如果没有的话,那么你也就可以 close这个SOCKET,发送FIN报文给对方,也即关闭连接。所以你在CLOSE_WAIT状态下,需要完成的事情是等待你去关闭连接。(被动方)
LAST_ACK: 这个状态还是比较容易好理解的,它是被动关闭一方在发送FIN报文后,最后等待对方的ACK报文。当收到ACK报文后,也即可以进入到CLOSED可用状态了。(被动方)
TIME_WAIT: 表示收到了对方的FIN报文,并发送出了ACK报文,就等2MSL后即可回到CLOSED可用状态了。如果FINWAIT1状态下,收到了对方同时带FIN标志和ACK标志的报文时,可以直接进入到TIME_WAIT状态,而无须经过FIN_WAIT_2状态。(主动方)
CLOSED: 表示连接中断。