1 2 3 4 5 | TCP三次握手流程: 客户端发出SYN到服务端,服务端回复SYN+ACK给客户端,客户端再次收到之后, 回复ACK给服务端,至此三次握手成功,即一旦完成三次握手,双方都处于 ESTABLISHED 状态,此时连接就已建立完成,客户端和服务端就可以相互 发送数据了。 |
1 2 | 如何在Linux中查看TCP状态? netstat -napt |
1 2 3 4 5 6 7 | TCP握手为什么是三次,不是2次或者4次? 片面的回答:因为三次握手才能保证双方具有接收和发送的能力 其实原因有以下几种: 三次握手才可以阻止重复历史连接的初始化(主要原因) 三次握手才可以同步双方的初始序列号 三次握手才可以避免资源浪费 重点掌握如何避免重复历史连接或者造成重复历史连接的成因 |
1 2 3 4 5 | 为什么每次建立 TCP 连接时,初始化的序列号都要求不一样呢? 为了防止历史报文被下一个相同四元组的连接接收(主要方面); 为了安全性,防止黑客伪造的相同序列号的 TCP 报文被对方接收; 如果每次建立连接,客户端和服务端的初始化序列号都是一样的话, 很容易出现历史报文被下一个相同四元组的连接接收的问题。 |
1 2 | 既然 IP 层会分片,为什么 TCP 层还需要 MSS 呢? 简而言之是为了提升传输的效率,IP层分片传输的效率极低 |
1 2 3 | 第一次握手丢失了,会发生什么? 客户端一般一开始会重传SYN包,重试次数达到内核参数tcp_syn_retries上限时, 重传断开,客户端断开连接。 |
1 2 3 4 5 6 7 8 9 | 第二次握手丢失了,会发生什么? 第二次握手的ACK其实是对第一次握手报文的确认;SYN是服务端发起建立TCP连接的报文; 所以说,第二次握手丢了,那么客户端就收不到第二次握手的确认报文, 于是客户端会重新发送第一次握手报文SYN,服务端需要第三次握手发送ACK 才能确认第二次握手是成功的,所以,第二次握手丢失,客户端无法发送ACK 回复给服务端,服务端以为二次握手不成功,所以也会重发二次握手SYN+ACK, 综上,二次握手丢失,客户端和服务端都会重发对应报文,直到断开连接。 客户端会重传 SYN 报文,也就是第一次握手,最大重传次数由 tcp_syn_retries内核参数决定; 服务端会重传 SYN-ACK 报文,也就是第二次握手,最大重传次数由 tcp_synack_retries 内核参数决定。 |
1 2 3 | 第三次握手丢失了,会发生什么? 根据内核参数 tcp_synack_retries的设置,三次握手没收到,服务端会重发 SYN+ACK报文,达到次数后,还未收到三次握手ACK报文,即刻断开TCP连接。 |
1 2 3 4 5 6 7 8 9 10 11 12 | 什么是 SYN 攻击?如何避免 SYN 攻击? SYN 攻击方式最直接的表现就会把 TCP 半连接队列打满,这样当 TCP 半连接队列满了, 后续再在收到 SYN 报文就会丢弃,导致客户端无法和服务端建立连接。 直白一点就是直接占满服务器访问端的TCP半连接队列(别称:SYN 队列), 使得别的客户端无法与服务器正常连接 避免 SYN 攻击方式,可以有以下四种方法: 调大 netdev_max_backlog; 增大 TCP 半连接队列; 开启 tcp_syncookies; 减少 SYN+ACK 重传次数 具体实现请百度 |