背景
今天在排查问题的时候通过netstat命令在查看连接转态的时候看到一堆连接状态,比如:ESTABLISHED,CLOSE_WAIT,TIME_WAIT,LISTEN。看到这些状态好像就只认识LISTEN哦,在认真看看,这些不就是tcp连接和断开所处的一些转态吗? 于是,下班了就准备好好在回忆下这方面的知识!
说到TCP的时候我们总是会将IP结合起来,因为TCP/IP协议。实际情况下呢,TCP处于osi的传输层,IP属于osi的网络层。既然提到了OSI七层模型,那在说TCP/IP的前,先简单介绍下OSI的七层模型吧。
介绍
一. OSI七层模型
1. 什么是OSI?
OSI(Open System Interconnection)。参考模型是国际标准化组织(ISO)制定的一个用于计算机或通信系统间互联的标准体系。是已经约定俗成的,我们无法改变的。
2. 哪七层呢?
物理层:一般指物理链接,比如网线,光纤,光缆;物理层的传输单位是位(bit),比特流。
数据链路层:该层的的最小数据单元叫数据帧,数据帧分为head和data两部分,其中head长度固定18个字节,head由原mac,目的mac(原目mac各占6个字节,)数据类型占6个字节;data:主要存放网络层的整体数据,最迟1500个字节,超过最大限制就要分片。
网络层:为数据在节点之间传输创建逻辑链路,并分组转发数据。该层的最小传输单元叫数据包;也由于head和data两部分组成。head包含原ip,目的ip;data主要存放传输层的整体数据。
传输层:提供进程之间的逻辑通讯,该层的最小传输单元是数据段。
会话层:建立端连接,并提供访问验证和回话管理。
表示层:提供数据格式化转换服务,比如加密解密,压缩解压缩等
应用层:访问网络服务的接口。
二. TCP/IP协议
TCP/IP协议是Internet互联网最基本的协议,其在一定程度上参考了七层ISO模型。在TCP/IP协议中,七层被简化为了四个层次。TCP/IP模型中的各种协议,依其功能不同,被分别归属到这四层之中,常被视为是简化过后的七层OSI模型。图:TCP/IP协议与OSI七层模型对照关系
应用层:应用层包括所有和应用程序协同工作,并利用基础网络交换应用程序的业务数据的协议。该层协议所提供的服务能直接支持用户应用。应用层协议包括HTTP、FTP(文件传输)、DNS(域名解析)等等。
传输层:为端到端的连接提供 提供传输服务,这种服务分为可靠传输(tcp协议:今天的主角),和不可靠传输(UDP协议)。
网络层:网络层负责将数据传输到目标地址,目标地址可以是多个网络通过路由器连接而成的某一个地址。同时网络层还负责寻找合适的路径到达对方计算机,并把数据包传送给对方,。网络层协议的代表包括:ICMP、IP、IGMP等。
网络接口层:该层对应的是osi中的数据链路层和物理层,因此该层的传输单元是比特,主要的协议是arp。
介绍了这么多,接下来就要重点说说我们的主角---TCP协议。
1. 什么是TCP协议?
TCP协议是一个面向连接的、可靠的传输协议,它提供一种可靠的字节流,能保证数据完整、无损并且按顺序到达。TCP尽量连续不断地测试网络的负载并且控制发送数据的速度以避免网络过载。
2. TCP连接的过程(三次握手)
第一次握手
由客户端向服务器 发出:客户端发送 SYN 报文,并进入 SYN_SENT 状态,等待服务器的确认。
第二次握手
由服务器向客户端发出:服务器收到 SYN 报文,需要给客户端发送 ACK 确认报文,同时服务器也要向客户端发送一个 SYN 报文,所以也就是向客户端发送 SYN + ACK 报文,此时服务器进入 SYN_RCVD 状态;发送报文内容如下。
1. ACK=1,表示接收到了你的报文;
2. ack=x+1,表示下次的报文中seq=x+1
3. SYN=1,表示向客户端发起建立连接的请求
4. seq=Y,表示随机产生的一个序列号
第三次握手
客户端收到 SYN + ACK 报文,向服务器发送确认包,客户端进入 ESTABLISHED 状态。待服务器收到客户端发送的 ACK 包也会进入 ESTABLISHED 状态,完成三次握手。报文信息如下:
1. ACK=1,表示接收到了你的报文信息;
2. ack=Y+1,表示下次发送的报文的seq为Y+1
3. seq=x+1.
3. TCP断开的过(四次挥手)
第一次挥手:
客户端发起 FIN 包(FIN = 1),客户端进入FIN_WAIT_1 状态。TCP 规定,即使 FIN 包不携带数据,也要消耗一个序号。
第二次挥手:
服务器端收到 FIN 包,发出确认包 (ack = u + 1),并带上自己的序号 seq=v,服务器端进入了 CLOSE_WAIT 状态。这个时候客户端已经没有数据要发送了,不过服务器端有数据发送的话,客户端依然需要接收。客户端接收到服务器端发送的 ACK 后,进入了 FIN_WAIT_2 状态。
第三次挥手:
服务器端数据发送完毕后,向客户端发送 FIN 包(seq=w ack=u+1),半连接状态下服务器可能又发送了一些数据,假设发送 seq 为 w。服务器此时进入了 LAST_ACK 状态。
第四次挥手:
客户端收到服务器的 FIN 包后,发出确认包(ACK=1,ack=w+1),此时客户端就进入了 TIME_WAIT 状态。注意此时 TCP 连接还没有释放,必须经过 2*MSL 后,才进入 CLOSED 状态。而服务器端收到客户端的确认包 ACK 后就进入了 CLOSED 状态,可以看出服务器端结束 TCP 连接的时间要比客户端早一些。
4. 为什么是三次握手,四次挥手?
其实在 TCP 握手的时候,接收端发送 SYN+ACK 的包是将一个 ACK和一个 SYN 合并到一个包中,所以减少了一次包的发送,三次完成握手。
四次挥手,因为 TCP 是全双工通信,在主动关闭方发送 FIN 包后,接收端可能还要发送数据,不能立即关闭服务器端到客户端的数据通道,所以也就不能将服务器端的 FIN 包与对客户端的 ACK 包合并发送,只能先确认ACK,然后服务器待无需发送数据时再发送 FIN 包,所以四次挥手时必须是四次数据包的交互。