首页 > 计算机网络 > TCP协议与🤝

TCP协议与🤝

作者:bin
目录
[隐藏]

一、TCP消息头格式

1.源端口,目标端口:用来标识消息从哪里来,到哪里去。

2.序号(seq),确认序号(ack):包的序号是用来保证包的顺序发送,确认序号是表示包确认收到

3.状态位:用于标识当前请求的行为状态,SYN(发起链接),ACK(回复),RST(重新链接),FIN(结束链接)

4.窗口大小:表示发送和接收放当前处理的窗口大小,用于做流量控制

5.校验和:这个和UDP都有,用于校验当前包内容是否损坏

二、TCP三次握手

三次握手的目的:

1.确认双方都可以正常的收发

2.确认后续包的序号

三次握手的过程:

1.(LISTEN):server开启一个服务,监听指定的端口

2.(SYN-SENT):client发送一个SYN(发起连接)的包到server监听的端口,其中包含序号x

3.(SYN-RCVD):server接收到client的SYN,回复一个SYN + ACK状态的包,并且回复client的ack(确认序列) = x + 1,同时设置server的seq(序列号) = y

4.(ESTABLISHED):客户端回复一个ACK状态的包,同时seq(序列号) = x + 1,ack(确认序列) = y+ 1

我们使用tcpdump来验证一下,在终端输入,其中en0为你的网卡

我zengbin@mac ~ % sudo tcpdump -i en0 host www.zengbingo.com -S

然后另开一个终端,使用curl进行一次完整的访问

curl www.zengbingo.com

我们可以看到3次握手

//第一次
16:22:36.763176 IP 172.20.16.246.63016 > 106.52.152.158.
http: Flags [S], seq 416244008, win 65535, options [mss 1460,nop,wscale 6,nop,nop,TS val 3885752949 ecr 0,sackOK,eol], length 0
//第二次
16:22:36.771890 IP 106.52.152.158.http > 172.20.16.246.63016:
 Flags [S.], seq 1520202174, ack 416244009, win 28960, options [mss 1424,sackOK,TS val 3770699262 ecr 3885752949,nop,wscale 7], length 0
//第三次
16:22:36.772009 IP 172.20.16.246.63016 > 106.52.152.158.
http: Flags [.], ack 1520202175, win 2051, options [nop,nop,TS val 3885752958 ecr 3770699262], length 0

三、TCP四次挥手

1.(FIN-WAIT-1):client发送FIN状态的包,同时seq=p,告诉server我要结束了

2.(CLOSED-WAIT):server回复一个ACK状态的包,同时ack=p+1,表示确认收到client的结束请求

3.(CLOSED-WAIT|FIN-WAIT-2):server发送一个FIN + ACK状态的包,同时seq =q,ack=p+1,告诉client我要结束了

4.(TIME-WAIT):client回复一个ACK包,ack=q+1,表示确认收到server的结束请求

5.(TIME-WAIT):等待2MSL(报文最大生存时间,通常30s、1min、2min),这里等待的目的是,如果server未收到client的ACK,那么server会进行重传FIN包,那么只要等待 :去向ACK消息最大存活时间(MSL) + 来向FIN消息的最大存活时间(MSL),的时间即可。


同样的,我们用三次握手的示例来验证四次挥手的过程

//第一次挥手,客户端说结束
16:30:42.089151 IP 172.20.16.246.63169 > 14.215.177.38.
http: Flags [F.], seq 903720639, ack 3908841077, win 4096, length 0

//第二次挥手,服务端收到结束
16:30:42.098919 IP 14.215.177.38.http > 172.20.16.246.63169:
 Flags [.], ack 903720640, win 908, length 0

//第三次挥手,服务端说结束
16:30:42.098928 IP 14.215.177.38.http > 172.20.16.246.63169: 
Flags [F.], seq 3908841077, ack 903720640, win 908, length 0

//第四次挥手,客户端收到结束
16:30:42.099098 IP 172.20.16.246.63169 > 14.215.177.38.http: 
Flags [.], ack 3908841078, win 4096, length 0

如果服务端没有消息需要发送了,第二次和第三次,服务端会进行合并

//第一次挥手
16:50:54.443571 IP 172.20.16.246.64804 > 106.52.152.158.http:
 Flags [F.], seq 478038655, ack 615087856, win 2048, options [nop,nop,TS val 3887436888 ecr 3772396927], length 0

//第二次第三次合并
16:50:54.451416 IP 106.52.152.158.http > 172.20.16.246.64804: 
Flags [F.], seq 615087856, ack 478038656, win 227, options [nop,nop,TS val 3772396939 ecr 3887436888], length 0

//第四次挥手
16:50:54.451460 IP 172.20.16.246.64804 > 106.52.152.158.http:
 Flags [.], ack 615087857, win 2048, options [nop,nop,TS val 3887436895 ecr 3772396939], length 0

四、TCP如何保证可靠性?

1.包头的校验和,通过对校验和的验证可以确定包内容是否正确

2.累计应答,通过上面三次握手和挥手,我们可以很直接的看到,每次ACK的ack(确认号)都会对上一次对方的SYN的seq(序号)进行确认+1。

3.超时重传

4.流量控制

5.拥塞控制

五、超时重传,快重传

如果发送一个报文,在RTT时间内没收到回复,那么就会认为丢包了,进行重传。

RTT(round trip time):报文一个往返的时间,TCP采用自适应重传算法(Adaptive Retransmission Algorithm)来动态计算往返时间,当出现丢包需要重传时,TCP的策略是超时间隔加倍。每当遇到一次超时重传的时候,都会将下一次超时时间间隔设为先前值的两倍。两次超时,就说明网络环境差,不宜频繁反复发送

快重传

例如:接收方发现 6 都已经接收了,就是 5没来,那肯定是丢了,于是发送三个 4的 ACK,要求下一个是 5。客户端收到 3 个4的ack,就会发现 5 的确又丢了,不等超时,马上重发

六、流量控制

包的确认中,同时会携带一个窗口的大小,rwnd(滑动窗口)。

1.server接收到client发送的内容后会存入缓存中,等待监听该端口的应用程序读取

2.如果应用程序处理能力弱,那么缓存很快会被塞满,此时server的处理能力是有限的

3.这是server就会在回复client的包头中加上当前可以处理的窗口大小,告诉client下次发送安窗口大小来发送,发多了也处理不过来。

4.如果server应用挂了,那么就没办法处理任何流量了,那么就会将窗口调整成0,同时为了避免低能窗口,server端不会空出一个字节就打开窗口,应该等窗口到一定大小再打开(通常是缓冲池到一半)

七、拥塞控制

流量控制是针对接server的处理能力在控制client的发送速率,拥塞控制是根据网络状况控制client到发送速率,TCP的拥塞控制是维护一个cwnd(拥塞窗口),主要避免,超时重传、丢包2种情况。

慢开始:发送的包按指数增长,第一次1个,第二次2个,第三次4个,第四次8个,直到出现超时。

超时重传:当出现超时时,会将速率降低为1,即cwnd = 1,重新开启慢重传

快重传(恢复):但是如果只丢了部分,server回复了3次ACK(五,中有提到),就会将cwnd = cwnd/2 + 3,即将速率降为一半 + 3个回复的ack,这种做法是TCP认为网络还不是很差,没必要从1开始。

您必须 [ 登录 ] 才能发表留言!