TCP三次握手,四次挥手(从状态的角度分析)

但是,我发觉我的知识来源大多来自《计算机网络-自顶向下》那本,这本书没有过多的考虑TCP三次握手中的相关状态转移细节,导致当时回答的并不是特别好,这次决定好好把这块知识好好巩固一下。
首先,我们先来一张大家都非常熟悉的图:
这里写图片描述
相信大家对这张图已经熟得不能再熟悉的,但我这次要应用程序的角度来说下:
1.客户端的socket(socket描述符)调用connect主动打开连接(当然要指定服务器的IP地址)这个时候,connect函数阻塞住等待下面的回信,然后发送SYN=1的包。
2.服务器端这时候创建socket,然后bind端口,开启监听,调用accept(阻塞),这时候收到了SYN。然后,从服务器上创建连接描述符,也就是创建了缓存空间,反回去发送SYN K,ack J+1(客户端的SYN),发送回客户端。
3.客户端这时候的connect返回,发送了ack K+1。服务端accept返回,连接成功,进行read,write读写,read这时候发生阻塞。
咋看之下,这个过程非常简单。但是,往深挖了就很多不会了,我也没太回答上来:

问题一

TCP在三次握手的时候一共传输了哪些消息:
SYN=1,ACK,序列号,看似只有这三个东西。还有目的IP,目的端口号,源IP,源端口号,还有一个最重要的接收窗口,接收窗口是在报文端里面进行控制的,但是我们的滑动窗口是在我们的操作系统中实现的。

问题二

滑动窗口的大小如何控制?
这个我们可以和拥塞窗口相互联系起来,刚开始的大小非常小,然后我们线性增大,一旦碰到了拥塞的情况,我们的窗口迅速减半。

问题三

TCP是几元组?
五元组,分别是源端口,源IP,目的端口,目的IP,还有一个运输层协议

下面,还是把四次握手的图一起放上来,好做理解:
这里写图片描述

你以为这样三次握手就完了吗。。。
我们还没讲状态呢?
来上图:
这里写图片描述
大家第一眼看这图肯定懵逼。没事,我们一步步来解决这个图。
对于三次握手:
(1).对于客户端而言:我们原来处理CLOSED的状态,然后我们客户端调用connect进行主动打开,发送SYN,之后我们便进入了SYN_SEND,这个时候我们应该准备的事情就是等待服务端的ACK了。
(2)对于服务端而言:开启服务端的时候从CLOSED转移到LISTEN,我们ACCEPT一个客户端的connect,我们处于被动打开的状态,从LISTEN状态转移到SYN_RCVD状态,并发送SYN K和ACK=SYN J+1。我们等待客户段的ACK应答。
(3)对于客户端而言:收到了服务端的SYN K和ACK=SYN J+1.客户端的阻塞connect连接成功,状态转移到了ESTABLISHED,并发送ACK=K+1,到服务端。
(4)对于服务端而言:收到客户端的ACK,状态转移到了ESTABLISHED。三次握手结束
(5)超时情况或应用close:继续转移到CLOSED的起始状态。

服务端和客户端都到了ESTABLISHED,说明可以进行传输信息。
这时候我们再来关注一下关闭服务器的场景是如何?
(1)客户端:调用close函数,发送FIN,到达FIN_WAIT_1状态,等待服务端的ACK过来。
(1)服务端:接收到客户端的FIN信息,发送ACK,并且到CLOSE_WAIT,服务端关闭与客户端的连接,并发送FIN.
(2)客户端:接收到服务端的ACK包,到达FIN_WAIT_2状态,并等待服务端发送FIN包。
(2)服务端:服务端开始发送FIN信息,到达LAST_ACK状态。
(3)客户端:接收到服务端的FIN信息,状态转移到TIME_WAIT状态。并发送 ACK包到服务端。
(3)服务端:接收到客户端的ACK信息,状态由LAST_ACK转移到CLOSED状态。
(3)客户端:超过2MSL时候后返回到CLOSED状态。

感觉字有点多,我们继续把这个过程简化到一张图上面:
这里写图片描述
这个图将我们的状态转移和三次握手、四次挥手的图都放在了一张折线图上面。
这就是我们要说的从状态转移的角度来说明TCP三次握手,四次挥手。
不知道大家有没发觉一个很奇怪的状态,也就是TIME_WAIT这个状态,是否判断2MSL超时。
给大家说明一下MSL是什么意思?MSL代表着IP报文能在互联网中存在的最长时间,2个MSL代表客户端和服务端的一个IP报文能在互联网中存在的最长时间总和。超过这个时间就说明出现了超时事件要进行重发。
那么,我们的TIME_WAIT的作用到底是什么呢,这里有两点:
1.实现终止TCP全双工连接的可靠性
2.允许老的重复分组在网络中消逝
对于1而言,假设在图中服务端的最后一个FIN未发送成功,经过一个MSL,之后服务端会重发送一个FIN。这就需要两个MSL时间让客户端进行审核。所以,客户端进入TIME_WAIT需要2个MSL时间。
对于2而言,是为了解决在结束这个连接之后,又建立起一个新的连接。为了避免这个新连接得到前一个连接的重发分组,2个MSL保证两个方向的重发分组都被抛弃掉了。
对于UDP而言,三次握手和四次挥手的过程将会被全部抛弃掉,这样看来,TCP将会比UDP多7节的传输过程。
Reference:UNIX网络编程

猜你喜欢

转载自blog.csdn.net/github_33873969/article/details/79619889