TCP全连接和半连接的问题探讨

本文详细介绍了TCP的3次握手过程,并深入讨论了TCP accept阶段涉及的半连接队列和全连接队列,包括backlog参数、队列溢出及其影响。通过实例分析和压测,揭示了全连接队列大小调整和半连接队列防护措施的重要性,以避免连接丢失和性能问题。
摘要由CSDN通过智能技术生成

个人博客: https://rebootcat.com/2020/11/14/tcp_accept/

从何说起

说起 tcp 的连接过程,想必 “3次握手4次挥手”是大家广为熟知的知识,那么关于更细节更底层的连接过程也许就很少人能讲清楚了。

所以本文会先简单回顾一下 tcp 的 3次握手过程,然后重点聊一下 tcp accept 的过程,涉及到 tcp 半连接队列、全连接队列等的内容。

回顾一下

3 次握手

要了解 3 次握手的过程,可能需要先熟悉一下 tcp 协议的格式:

  • tcp segment 的头部有两个 2字节的字段 source portdest port,分别表示本机端口以及目标端口,在 tcp 传输层是没有 IP 的概念的,那是 IP 层 的概念,IP 层协议会在 IP 协议的头部加上 src ipdest ip
  • 4 个字节的 seq,表示序列号,tcp 是可靠连接,不会乱序;
  • 4 个字节的 ack,表示确认号,表示对接收到的上一个报文的确认,值为 seq + 1;
  • 几个标志位:ACK,RST,SYN,FIN 这些是我们常用的,比较熟悉的。其中 ACK 简写为 “.”; RST 简写为 “R”; SYN 简写为 “S”; FIN 简写为 “F”;

注意: ack 和 ACK 是不一样的意思,一个是确认号,一个是标志位

了解了 tcp 协议的头部格式,那么再来讲一下 3 次握手的过程:

  1. 客户端对服务端发起建立连接的请求,发送一个 SYN 包(也就是 SYN 标志位设置为 1),同时随机生成一个 seq 值 x,然后客户端就处于 SYN_SENT 状态;
  2. 服务端收到客户端的连接请求,回复一个 SYN+ACK包(也就是设置 SYN 和 ACK 标志位为 1),同时随机生成一个 seq 值 y,然后确认号 ack = x + 1,也就是 client 的 seq +1,服务端进入 SYN_RECV 阶段;
  3. 客户端收到服务端的 SYN+ACK 包,会回复一个 ACK 包(也就是设置 ACK 标志位为 1),设置 seq = x + 1,ack 等于 服务端的 seq +1,也就是 ack = y+1,然后连接建立成功;

tcpdump 抓包

开一个终端执行以下命令作为服务端:

# 服务端
$ nc -l 10000

然后打开新的终端用 tcpdump 抓包:

# -i 表示监听所有网卡;

# -t 表示不打印 timestamp;

# -S 表示打印绝对的 seq 而不是相对的 seq number;

# port 10000 表示对 10000 端口进行抓包

$ tcpdump  -i any -t -S port 10000

然后再打开一个终端模拟客户端:

$ nc 127.0.0.1 10000

观察 tcpdump 的输出如下:

IP Jia.22921 > 192.168.1.7.ndmp: Flags [S], seq 614247470, win 29200, options [mss 1460,sackOK,TS val 159627770 ecr 0], length 0
IP 192.168.1.7.ndmp > Jia.22921: Flags [S.], seq 1720434034, ack 614247471, win 65160, options [mss 1460,sackOK,TS val 3002840224 ecr 159627770], length 0
IP Jia.22921 > 192.168.1.7.ndmp: Flags [.], ack 1720434035, win 29200, options [nop,nop,TS val 159627770 ecr 3002840224], length 0

分析以下上面的结果可以看到:

  1. 第一个包 Flags [S] 表示 SYN 包,seq 为随机值 614247470;

  2. 然后服务端回复了一个 Falgs [S.],也就是 SYN+ACK 包,同时设置 seq 为随机值 1720434034,设置 ack 为 614247470 + 1 = 614247471;

  3. 客户端收到之后,回复一个 Flags [.],也就是 ACK 包,同时设置 ack 为 1720434034 + 1 = 1720434035;

假如3次握手丢包了?

上面是正常情况的握手情况,假如握手过程中的任何一个包出现丢包呢会怎么样?比如受到了攻击,比如服务端宕机,服务端超时,客户端掉线,网络波动等。

所以接下来我们分析下 3 次握手过程中涉及到的连接队列。

tcp 内核参数

backlog 参数

https://linux.die.net/man/3/listen

The backlog ar

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值