TCP字段详解与三次握手四次挥手过程

TCP字段详解与三次握手四次挥手过程

TCP数据包

在这里插入图片描述

术语含义
序号seq占4个字节,用来标记数据段的顺序,TCP把连接中发送的所有数据字节都编上一个序号
第一个字节的编号由本地随机产生;给字节编上序号后,就给每一个报文段指派一个序号;
序号seq就是这个报文段中的第一个字节的数据编号
确认号ack占4个字节,表示期待收到对方下一个报文段的第一个数据字节的序号;
确认号ack指的是期望接收到下一个字节的编号
当前报文段最后一个字节的编号+1即为将发送的确认号
数据偏移由于头部有可选字段,长度不固定,因此数据偏移指出TCP报文数据距离TCP报文起始处有多远
URG紧急指针标志,为1时,紧急指针有效。表示此报文段中有紧急数据要被优先处理
ACK确认序号标志,为1时,确认号有效
PSHpush标志,为1时,接收端应用程序应该从TCP缓冲区把数据读走,不用等到缓存填满
RST重置连接标志,为1时,说明当前tcp出现严重错误,对方要求重新建立连接
SYN同步序列号,为1时,请求建立连接,并在其序列号的字段进行序列号的初始值设定。
FINfinish标志,为1时,要求释放连接
滑动窗口(窗口)告知发送端,接收端的缓存大小,以此控制发送端发送的速率,从而流量控制
校验和对整个TCP报文段(TCP头部、TCP数据)以16位计算所得,由发送端计算和存储,接收端验证
紧急指针URG为1时有效,指出本报文段中紧急数据的字节数
可选项定义一些可选参数
MSS:每个TCP报文段中数据字段的最大长度
Windows scaling:窗口扩大选项
更多参考 https://wenku.baidu.com/view/5c288b51ad02de80d4d84066.html

三次握手

目的:为了确认连接

在这里插入图片描述

1.第一次握手

C => [syn] => S

SYN=1,seq=x

客户端发送SYN包到服务器

客户端进入SYN_SEND状态

2.第二次握手

C <= [syn/ack] <= S

SYN=1,ACK=1,seq=y,ack=x+1

服务端确认客户端的SYN,发送ACK确认包+SYN

发送SYN+ACK包到客户器,进入SYN_RECV状态

3.三次握手

C => [ack] => S

ACK=1,seq=x+1,ack=y+1

客户端收到SYN+ACK包,向服务端发送ACK确认包**(ack=k+1)**

服务端与客户端进入ESTABLISHED状态

如果此时丢包,服务端会不断重试直至超时

⚠️针对SYN Flood的防护措施

SYN队列满后,通过tcp_syncookies参数回发SYN Cookie
若正常连接则客户端会回发SYNCookie

建立连接后,客户端出现故障时

⚠️保活机制

配置了保活的一端会发送保活探测报文,若未接收到则继续发送
尝试次数达到保活探测数仍未收到响应则中断连接

在这里插入图片描述

四次挥手

目的:终止连接,TCP四次挥手的流程如下:

在这里插入图片描述

客户端或服务端都可发起主动关闭

假设客户端发起关闭

1.第一次挥手

C => [syn/FIN] => S

FIN=1,seq=u

客户端发送FIN/SYN包**(FIN=1,syn=u**(由服务器传送来的最后一次数据的最后一个序号+1)**)**到服务器

客户端进入FIN-WAIT-1

2.第二次挥手

服务器发送SYN+ACK包,syn=v,ack=u+1
C <= [syn/ack] <= S
ACK=1,seq=v,ack=u+1(与SYN相同,一个FIN占用一个序号)

服务器通知上层应用进程:客户端已经没有数据要发送了

服务器进入半关闭CLOCE-WAIT状态
客户端进入FIN-WAIT-2状态,等待服务器发送第三次挥手报文

此时可能还有正在发送中的数据

3.第三次挥手

服务器发送完数据后,发送第三次挥手报文:
C <= [syn/ack/FIN] <= S
FIN=1,ack=u+1,seq=w(可能已经发送了数据)

服务端进入LAST-ACK状态

客户端接受到报文后进入TIME-WAIT

4.第四次挥手

C => [syn/ack] => S
seq=u+1,ack=w+1

服务端CLOSED

客户端等待2MSL时间CLOCED

MSL最长报文段寿命

在这里插入图片描述

为什么要有TIME_WAIT?

1.确保有足够时间让对方收到ACK包
如果被动关闭端没有收到ACK就会重发FIN包,一来一回即为2*TIME_WAIT

2.避免新旧连接混淆
有些路由器会缓存IP数据包,延迟收到的包可能会与新连接混淆

为什么要四次挥手才能断开连接

因为全双工,发送方和接收方都需要FIN报文和ACK报文

服务器出现大量CLOSE_WAIT状态的原因

对方关闭socket连接,我方忙于读写操作,没有及时关闭连接
1.检查代码,释放资源的代码
2.检查配置,特别是处理请求的线程配置

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值