java三次握手丢包_TCP—三次握手丢包——实验记录

复制代码

文本主要是动手操作“小林coding”作者的丢包分析实验,感谢大神的总结,让我对TCP有了更深次的认识; 通过使用tcpdump、Wireshark抓包工具分析TCP丢包时过程;能跟踪、分析TCP三次握手具体发生了什么、不仅仅停留在理论与看blog上。

TCP第一次握手SYN包丢包

// 发送一个不存在地址的请求,用与模拟丢包情况

[root@~]$date; curl http://47.98.161.20 ;date

Sat Jun 6 15:06:06 CST 2020

curl: (7) Failed connect to 47.98.161.20:80; Connection timed out

Sat Jun 6 15:08:14 CST 2020

// 通过tcpdump抓包分析

[root@~]$tcpdump tcp and host 47.98.161.20 -w http-80-one.pcap

tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes

^C7 packets captured

7 packets received by filter

0 packets dropped by kernel

使用Wireshark分析如下图复制代码

5bffb7bf5053186fe2b6f550d369c148.png

49f28c340a1f568f61af535888f9a9f2.png

重试发生了6次;由以下系统参数决定

[root@~]$cat /proc/sys/net/ipv4/tcp_syn_retries

6

我们对该参数进行一次修改

echo 2 > /proc/sys/net/ipv4/tcp_syn_retries

重新进行一次抓包请求

[root@~]$date; curl http://47.98.161.20 ;date

Sat Jun 6 15:57:48 CST 2020

curl: (7) Failed connect to 47.98.161.20:80; Connection timed out

Sat Jun 6 15:57:55 CST 2020

发现本次消耗的时长变短了

通过Wireshark分析如下图复制代码

97903f85e94f9c1e06e96c2d57fa2970.png

总结:

当客户端发起的TCP第一次握手syn包,在超时时间内没收到服务端的ack,就会在超时重传syn数据包,

每次超时重传的RTO是翻倍上涨的,直到syn包的重传次数到达tcp_syn_retries值后,客户端不再发送 syn包。复制代码

TCP第二次握手SYN包丢包

为了模拟客户端收不到服务端的响应,添加防火墙设置

// 添加防火墙

iptables -I INPUT -s 47.98.161.8 -j DROP

// 发送请求

[root@PHP-6-20 ~]# curl http://47.98.161.8:8080

curl: (7) Failed connect to 47.98.161.8:8080; 连接超时

// 抓包

[root@PHP-6-20 oyj]# tcpdump tcp and host 47.98.161.8 -w http-80-two.pcap

tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes

^C6 packets captured

6 packets received by filter

0 packets dropped by kernel

通过Wireshark分析如下图复制代码

e30db23c1c063ccf2d46ce7b547a8c79.png

b71854c6ae11b848241099a5c4d2f8d3.png

客户端角度:

客户端发起SYN后,由于防火墙屏蔽了服务端的所有数据包,所以curl是无法收到服务端的SYN、ACK包,

当发生超时后,就会重传SYN包;

服务端角度:

服务端收到客户的SYN包后,就会回SYN、ACK包,但是客户端一直没有回ACK,服务端在超时后,重传了

SYN、ACK 包,接着一会,客户端超时重传的SYN包又抵达了服务端,服务端收到后,超时定时器就重新

计时,然后回SYN、ACK包,所以相当于服务端的超时定时器只触发了一次,又被重置了;

客户端SYN超时重传次数达到了2次(上面重置过,一般tcp_syn_retries 默认值5次),就不再继

续发送SYN包了。

总结:

可以发现,当第二次握手的SYN、ACK丢包时,客户端会超时重发SYN包,服务端也会超时重传SYN、ACK包。

复制代码

TCP第三次握手SYN包丢包

// 服务端添加防火墙,用于拒绝客户端的三次握手的ACK操作

iptables -I INPUT -s 192.168.12.37 -p tcp --tcp-flag ACK ACK -j DROP

// 具体操作分一下客户端和服务端复制代码

// 客户端

// 简历TCP连接

telnet 47.98.161.8:8080

[root@PHP-6-20 ~]# telnet 47.98.161.8 8080

Trying 47.98.161.8...

Connected to 47.98.161.8.

Escape character is '^]'.

// 抓包

[root@PHP-6-20 oyj]# tcpdump tcp and host 47.98.161.8 -w http-80-three.pcap

// 监控TCP状态

[root@PHP-6-20 ~]# netstat -napt | grep 47.98.161.8

tcp 0 0 192.168.6.20:38004 47.98.161.8:8080 ESTABLISHED 14424/telnet

[root@PHP-6-20 ~]#复制代码

e055dc025d51d338a32d3b51420b1cda.png

8c80b79df6082cb5cecead39269b0bef.png

// 服务端

[root@supervisor]$netstat -napt | grep 182.48.105.10

tcp 0 0 172.16.152.136:8080 182.48.105.10:32516 SYN_RECV -

复制代码

总结

在建立 TCP 连接时,如果第三次握手的ACK,服务端无法收到,则服务端就会短暂处于SYN_RECV状态,

而客户端会处于 ESTABLISHED 状态。

由于服务端一直收不到TCP第三次握手的ACK,则会一直重传SYN、ACK包,直到重传次数超过tcp_synack_retries

值(默认值5次)后,服务端就会断开 TCP 连接。

复制代码

TCP重传次数设置:

// 第一次握手重传次数限制

cat /proc/sys/net/ipv4/tcp_syn_retries

// 第二次握手重传次数限制

cat /proc/sys/net/ipv4/tcp_synack_retries

// 数据包最大重传次数限制

cat /proc/sys/net/ipv4/tcp_retries2复制代码

Linux控制keepalive有三个参数:

net.ipv4.tcp_keepalive_time=7200net.ipv4.tcp_keepalive_intvl=75 net.ipv4.tcp_keepalive_probes=9保活时间net.ipv4.tcp_keepalive_time、保活时间间隔net.ipv4.tcp_keepalive_intvl、保活探测次数net.ipv4.tcp_keepalive_probes,是否复用time_wait net.ipv4.tcp_tw_reuse默认值分别是 7200 秒(2 小时)、75 秒和 9 次探测复制代码

参考

表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
相关推荐
©️2020 CSDN 皮肤主题: 游动-白 设计师:白松林 返回首页