TCP 三次握手
- client:发送SYN包至,并进入SYN_SENT状态,等待服务器确认
- sever:收到的SYN包,发送ACK,同时发送自己的SYN,进入SYN_RCVD状态
- client:收到SYN+ACK后,进入ESTABLISHED状态,发送服务器SYN包的确认ACK,服务器接收客户端ACK后,进入ESTABLISHED状态
SYN(Synchronize Sequence Numbers)同步序列编号,建立连接时使用的握手信号
同步:函数调用者需等待函数执行完成后才能进到下一步
当客户端和服务器都进入ESTABLISHED状态后,客户端和服务器之间就可以开始双向传递数据了
syn_sent是主动打开方的「半打开」状态,syn package has been sent
syn_rcvd是被动打开方的「半打开」状态,syn package has been received
TCP四次挥手
- 主动关闭方:主动关闭方发送FIN并进入FIN_WAIT1状态
- 被动关闭方:被动关闭方接收到主动关闭方发送的FIN并发送ACK,此时被动关闭方进入CLOSE_WAIT状态;主动关闭方收到被动关闭方的ACK后,进入FIN_WAIT2状态
- 被动关闭方:被动关闭方发送一个FIN并进入LAST_ACK状态
- 主动关闭方:主动关闭方收到被动关闭方发送的FIN并发送ACK,此时主动关闭方进入TIME_WAIT状态,经过2MSL时间后关闭连接;被动关闭方收到主动关闭方的ACK后,关闭连接
TIME_WAIT状态:标准的持续时间是4分钟,4分钟后才会进入到closed状态,释放套接字资源
MSL:就是maximium segment lifetime
——最长报文寿命
四次挥手也并不总是四次挥手,中间的两个动作有时候是可以合并一起进行的,这个时候就成了三次挥手,主动关闭方就会从fin_wait_1
状态直接进入到time_wait
状态,跳过了fin_wait_2
状态。
TCP 数据传输
TCP 数据传输就是两个人隔空对话,差了一点距离,所以需要对方反复确认听见了自己的话。
张三喊了一句话(data),李四听见了之后要向张三回复自己听见了(ack)。
如果张三喊了一句,半天没听到李四回复,张三就认为自己的话被大风吹走了,李四没听见,所以需要重新喊话,这就是tcp重传。
也有可能是李四听到了张三的话,但是李四向张三的回复被大风吹走了,以至于张三没听见李四的回复。
张三并不能判断究竟是自己的话被大风吹走了还是李四的回复被大风吹走了,张三也不用管,重传一下就是。
既然会重传,李四就有可能同一句话听见了两次,这就是「去重」。「重传」和「去重」工作操作系统的网络内核模块都已经帮我们处理好了,用户层是不用关心的。
张三可以向李四喊话,同样李四也可以向张三喊话,因为tcp链接是「双工的」,双方都可以主动发起数据传输。不过无论是哪方喊话,都需要收到对方的确认才能认为对方收到了自己的喊话。
张三可能是个高射炮,一说连说了八句话,这时候李四可以不用一句一句回复,而是连续听了这八句话之后,一起向对方回复说前面你说的八句话我都听见了,这就是批量ack。
但是张三也不能一次性说了太多话,李四的脑子短时间可能无法消化太多,两人之间需要有协商好的合适的发送和接受速率,这个就是「TCP窗口大小」。
网络环境的数据交互同人类之间的对话还要复杂一些,它存在数据包乱序的现象。
同一个来源发出来的不同数据包在「网际路由」上可能会走过不同的路径,最终达到同一个地方时,顺序就不一样了。
操作系统的网络内核模块会负责对数据包进行排序,到用户层时顺序就已经完全一致了。