一、机器准备
本次实验使用两台机器,一台作为服务端,一台作为客户端,运行linux系统。
服务端 192.168.12.36 客户端 192.168.12.37 两台机器各自运行某模块服务,两模块为上下游关系,可以进行通信。 二、模拟TCP 第⼀次握⼿ SYN 丢包 为了模拟 TCP 第⼀次握⼿ SYN 丢包的情况,我是在拔掉服务器的⽹线后,⽴刻在客户端给服务端发送请求。 或者粗暴地在服务端设置iptables规则,使其丢掉来自客户端的所有请求 iptables -A INPUT -s 192.168.12.36 -j DROP 然后在客户端执行tcmdump,抓取访问服务端的数据包 tcpdump tcp port xxx and host 192.168.12.37 -w tcp_sys_timeout.pcap 接着,把 tcp_sys_timeout.pcap ⽂件⽤ Wireshark 打开并进行分析。 总结:通过实验结果,我们可以得知,当客户端发起的 TCP 第⼀次握⼿ SYN 包,在超时时间内没收到服务端的 ACK,就会在超时重传 SYN 数据包,每次超时重传的 RTO 是翻倍上涨的,直到 SYN 包的重传次数到达 tcp_syn_retries (/proc/sys/net/ipv4/tcp_syn_retries)值后,客户端不再发送 SYN 包。 三、模拟TCP 第⼆次握⼿ SYN、ACK 丢包 为了模拟客户端收不到服务端第⼆次握⼿ SYN、ACK 包,我的做法是在客户端加上防⽕墙限制,直接粗暴的把来 ⾃服务端的数据都丢弃,防⽕墙的配置如下: iptables -I INPUT -s 192.168.12.36 -j DROP 接着在客户端发送请求给服务端,并在客户端使用tcpdump命令抓取数据包,然后使用 Wireshark 进行分析。 总结:通过实验结果,我们可以得知,当 TCP 第⼆次握⼿ SYN、ACK 包丢了后,客户端 SYN 包会发⽣超时重 传,服务端 SYN、ACK 也会发⽣超时重传。 客户端 SYN 包超时重传的最⼤次数,是由 tcp_syn_retries (/proc/sys/net/ipv4/tcp_syn_retries)决定的,默认值是 5 次;服务端 SYN、ACK 包时重传的最⼤次数,是由 tcp_synack_retries(/proc/sys/net/ipv4/tcp_synack_retries) 决定的,默认值是 5 次。 四、模拟TCP 第三次握⼿ ACK 丢包 为了模拟 TCP 第三次握⼿ ACK 包丢,我的实验⽅法是在服务端配置防⽕墙,屏蔽客户端 TCP 报⽂中标志位是 ACK 的包,也就是当服务端收到客户端的 TCP ACK 的报⽂时就会丢弃,iptables 配置命令如下: iptables -I INPUT -s 192.168.12.37 -p tcp --tcp-flag ACK ACK -j DROP 然后在客户端执行tcpdump抓取数据包,在客户端给服务端发送请求。 此时,由于服务端收不到第三次握⼿的 ACK 包,所以⼀直处于 SYN_RECV 状态; ⽽客户端是已完成 TCP 连接建⽴,处于 ESTABLISHED 状态; 过了 1 分钟后,观察发现服务端的 TCP 连接不⻅了; 持续「好⻓」⼀段时间,客户端才断开连接。 总结:在建⽴ TCP 连接时,如果第三次握⼿的 ACK,服务端⽆法收到,则服务端就会短暂处于 SYN_RECV 状态,⽽ 客户端会处于 ESTABLISHED 状态。 由于服务端⼀直收不到 TCP 第三次握⼿的 ACK,则会⼀直重传 SYN、ACK 包,直到重传次数超过 tcp_synack_retries 值(默认值 5 次)后,服务端就会断开 TCP 连接。 ⽽客户端则会有两种情况: 如果客户端没发送数据包,⼀直处于 ESTABLISHED 状态,然后经过 2 ⼩时 11 分 15 秒(触发了保活机制)才可以发现⼀个 【死亡】连接,于是客户端连接就会断开连接。 如果客户端发送了数据包,⼀直没有收到服务端对该数据包的确认报⽂,则会⼀直重传该数据包,直到重传次数超过 tcp_retries2 值(/proc/sys/net/ipv4/tcp_retries2,默认值 15 次)后,客户端就会断开 TCP 连接。 五、模拟TCP 三次握手后丢包 这种情况就比较简单了,如果需要服务端丢包,可以在服务端使用gdb -p xxx(进程号)阻塞住服务端进行即可。客户端同理。 标签:及建,ACK,SYN,TCP,tcp,连接,服务端,客户端 From: https://www.cnblogs.com/justloving/p/16775380.html