传输层的TCP协议中,我们被问到便会想起一句经典的话“TCP/IP协议是面向连接的,传输数据可靠的,面向字节流的”,话说起来容易,但是其中细究其原理,还是很复杂的
面向连接:
在TCP网络通信模型中,客户端和服务器之间的进程交互是面向连接的——面向连接就意味着必须确认双方的连接是可靠的,如何确认双方的连接是可靠的,以及断开连接俩端是如何进行的,这里我们引入了“三次握手,四次挥手”的总结思想
对于TCP来说,
1.服务器首先创建一个监听socket即Listen_socket,来获取来自客户端的通信请求
2.客户端向服务器发生一个通信请求,请求完成后创立通信socket,此时要与客户端的socket建立连接
3,客户端向服务器端发送请求标志位“SYN= 1”的请求数据,自己进入SYN_SENT状态,表示等待服务器端回复的ACK;
这里插入一下TCP传输过程中数据协议的形式:
(1)16位源端端口和16位对端端口:描述通信的俩端
(2)32位序号+32位确认序号:实现TCP传输的包序管理以及确认应答
(3)4位头部长度:以4字节为单位,表示TCP报头最大长度为60字节——最小是固定的20字节 ——》先取出20固定长度头部,根据头部中长度,取出剩余长度选项数据,剩下的就是data
(4)6位保留位
(5)6位标志位:
URG:紧急指针标志
ACK:用于确认请求,确认标志
PSH:用于提示尽快取出缓存区里的数据
RST:当产生主机奔溃什么的重大连接错误时,或者被拒绝连接时,重新发送的连接请求
SYN:请求包,用于连接socket的时候发送
FIN:finish包,用于表示自己进程不再接收数据
(6)窗口大小:用于实现滑动窗口机制,传输数据是控制流量,控制发送端的发送数据适应接收端的数据处理能力
(7)16位校验和:校验数据的一致性
(8)16位 紧急指针:“外带数据”–这里不讨论,有兴趣可以自己看一看
(9)0-40位字节选项数据:比如建立连接时会协商MSS
3.服务端收到SYN,本来只需要回复一下ACK确认给客户端,然后服务端在向客户端发送SYN,等待客户端ACK回复,这里过程是冗余的,因为对于服务端此时来说,连接过程是不需要考虑实际数据传输的(这里与四次挥手——断开连接有很大区别),所以可以将服务器端的ACK和SYN一起置1发送給客户端,此时服务器端进入SYN-RECV状态,表示等待客户端的ACK回复;
4.客户度收到服务器端的回复进入就绪状态(ESTABLENED状态),收到服务器端SYN,回复ACK
5.服务器端收到ACK进入就绪状态(ESTABLENED)
用图片来表为:
至此,便是一个完整的“三次握手”,三次握手保证了以客户端为主的连接请求与确认,也保证了以服务器为主的连接请求与确认,体现了“面向连接”的思想,面向连接即保证双方都有完整的连接过程
————————————————————————————————————————————————————-
6.此时连接已经创建好了,可以进行数据传输了
—————————————————————————————————————————————————————
7.如果在传输过程中,有某一端(这里借用客户端,实际情况俩端都有可能,叫做主动请求端)表示自己不在接收对端(这里拿服务器端表示,表示被动接受端)的数据了,这时候就会向对端发送一个“FIN包“”,然后自己进入FIN_WAIT1状态
8.对端(被动接受端)收到(主动请求端)的FIN,回复ACK表示确认,注意:这里并不代表主动请求端不再发送数据了,这里影响到被动接收端不可以将FIN和ACK一起发送,此时主动请求端进入FIN_WAIT2状态,被动接收端进入CLOSE_WAIT状态
9.当被动接收端表示自己也不再发送数据了,向对端发送FIN,然后自己进入LAST_ACK状态,表示等待最后的ACK应答,此时对端进入TIME_WAIT状态
10.主动请求端收到对端的FIN,确认ACK发送給对端,对端收到ACK彻底断开,进入CLOSE状态
11.TIME_WAIT状态持续一段时间(一般为2MSS)后进入CLOSE状态表示彻底关闭
用图片来表示为:
至此,便是一个完整的“四次挥手”,四次挥手同样保证了双方都完整的确立了结束的过程,体现了“面向连接”的思想
值得注意的是
:三次握手与四次挥手中,为什么会是“三次”和“四次”?
四次挥手过程中除了断开连接外,需要考虑期间的数据传输,比较发送FIN包仅仅表示自己不再接收数据了,这与三次握手中单一的连接过程有区别,当然,实际使用情况下,若是一端不再接收时,这端也不再发送了,那么对端也就没有持续下去的意义了,也可以将FIN和ACK一起打包返回,变成“三次挥手”
,有时候会出现多个TIME_WAITE?
TIME_WAITE状态存在于主动关闭方,表示对端多个socke发送FIN包,常常见于爬虫软件
, 有时候会出现多个CLOSE_WAITE?
CLOSE_WAITE出现在被动接收端,是收到了好多主动请求端的FIN包,出现的原因多是关闭的连接但是套接字依旧存在,没有在关闭连接后及时的关闭套接字
, 为什么要有TIME_WAITE状态?
用于预防最后一次ACK如果丢了,就会重传FIN,但是这个时候倘若前一次FIN后立即释放了,可能在相同地址下已经建立起新的socket,这种时候就会出现很大的问题,因此设置TIME_WAIT状态,用于确保最后ACK传输成功,也就是正确处理到收到的FIN包,让这个FIN包消失再网络里
下次将继续分析可靠传输和面向字节流,分析里面的一些思想和机制,诸如滑动窗口机制,延迟回复机制等等;
谢谢观看,诚邀批评指正
TCP/IP基础概念详解(面向连接部分)
未经允许不得转载:爱站程序员基地 » TCP/IP基础概念详解(面向连接部分)