TCP
简介
TCP是在IP网络层之上的传输层协议,用于提供port到port面向连接的可靠的字节流传输
TCP结构

序列号:在初次建立连接的时候,客户端和服务端都会为「本次的连接」随机初始化一个序列号。(纵观整个TCP流程中,序列号可以用来解决网络包乱序的问题)
确认号:该字段表示「接收端」告诉「发送端」对上一个数据包已经成功接收,一般而言确认号等于上一次接收到的[序列号+1](确认号可以⽤来解决网络包丢失的问题)
flag标志位:
SYN=1,表示希望创建连接
ACK=1,表示接收到消息,确认号字段有效
FIN=1,表示希望断开连接
RST=1,表示TCP连接出现异常,需要断开
TCP三次握手
TCP三次握手的目的:确认客户端和服务端通信双方的序列号

过程如下:
1、在最开始的时候,客户端和服务端都处于 CLOSE 状态
2、客户端:SYN seq=client_isn(ISN:internal statement number序列号随机生成),状态变成 SYN_SEND
3、服务端:SYN、ACK seq=server_isn,ack=client_isn+1 状态变成 SYN-REVD
4、客户端 :ACK ack=server_isn+1 进入 ESTABLISHED 状态
明确server端接收到了我的序列号(从ack=client_isn+1得知),需要让服务端也知道我能接收到他的消息。
5、服务端:服务端接收到客户端的报文之后,也进入 ESTABLISHED 状态
TCP连接两次握手行吗?
不行,两次握手只能保证客户端知道自己的序列号同步给服务端了,但服务端不清楚自己的序列号能否被客户端接受
序列号为什么是随机的?
1、安全性考虑 2、方便通信双方丢弃非本连接的报文
网络是不可靠的,那建立连接不是会经过三次握手吗?那要是在中途丢了,怎么办?
- 第一个包丢了
- 客户端迟迟没接收到服务端的ACK包,会周期性超时重传,直到收到服务端的ACK
- 第二个包丢了
- 服务端迟迟没接收到客户端的SYN、ACK包,会周期性超时重传,直到收到客户端的ACK
- 第三个包丢了,客户端单方面进入ESTABLISHED
- 客户端和服务端都没有发送数据
- 服务端周期性超时重传
- 如果这时候客户端已经要发送数据了,服务端接收到了ACK + Data数据包,那自然就切换到 ESTABLISHED 状态下,并且接收客户端的Data数据包
- 如果此时服务端要发送数据了,但发送不了,会一直周期性超时重传SYN + ACK,直到接收到客户端的ACK包
- 客户端和服务端都没有发送数据
四次挥手

四次挥手的过程
(客户端说我要断开了,服务端说收到,等等,马上,服务端说来吧断开吧,客户端 收到)
1、建立连接后,客户端和服务端都处于ESTABLISHED状态,双方都可以发起断开连接,以客户端为例
2、客户端:FIN,然后进入FIN_WAIT_1状态
3、服务端:ACK,然后进入CLOSE_WAIT状态
4、客户单:接收到ACK后,进入FIN_WAIT_2状态
5、服务端确认完没有待发送数据后,发送 FIN ACK ,自己进入LAST_WAIT状态
6、客户端:ACK,然后进入FIN_WAIT_1状态
7、服务端:进入CLOSE状态
9、客户端:等待2MSL(Maximum Segment Lifetime:最长报文段寿命)后,进入close状态
TIME_WAIT (等待 2MSL)状态的作用
1、连接断开后,创建新连接时,网络中的残余数据都丢失了,不会影响到新连接
2、确保服务端能接受到最后一个ACK报文段,从而进入都进入CLOSE状态(如果server接受不到client的ACK,会超时重发 FIN+ACK),客户端重新等待2MSL,知道服务端接受成功,双方都进入CLOSE状态
TCP连接到底是什么?如何理解
TCP连接其实是客户端服务端双方之间确认状态信息,比如建立连接时序列号等等,本质上是维持一个一个状态,具有连接特性
为什么TCP4次挥手时等待的时间是2MSL
1、为了让此次 TCP 连接中的所有报文在网络中消失、避免对下一次的连接造成影响:1、如果B迟迟收不到A的ACK,B会重发FIN。2、假设极端情况下A的ACK在MSL时到达了B,B在接收到的前一刻重传了FIN,这个FIN会在MSL内消失,所以A等待2MSL是为了处理所有的来自B的报文。