如何制作一个网站h5,做网页向网站提交数据,wordpress搭建软件下载,关键词首页排名代做1.TCP 三次握手过程是怎样的#xff1f;
TCP 是面向连接的协议#xff0c;所以使用 TCP 前必须先建立连接#xff0c;而建立连接是通过三次握手来进行的
1.一开始#xff0c;客户端和服务端都处于 CLOSE 状态。先是服务端主动监听某个端口#xff0c;处于 LISTEN 状态 2…1.TCP 三次握手过程是怎样的
TCP 是面向连接的协议所以使用 TCP 前必须先建立连接而建立连接是通过三次握手来进行的
1.一开始客户端和服务端都处于 CLOSE 状态。先是服务端主动监听某个端口处于 LISTEN 状态 2.客户端会随机初始化序号client_isn将此序号置于 TCP 首部的「序号」字段中同时把 SYN 标志位置为 1表示 SYN 报文。 接着把第一个 SYN 报文发送给服务端表示向服务端发起连接 该报文不包含应用层数据之后客户端处于 SYN-SENT 状态 3.服务端收到客户端的 SYN 报文后首先服务端也随机初始化自己的序号server_isn将此序号填入 TCP 首部的「序号」字段中其次把 TCP 首部的「确认应答号」字段填入 client_isn 1, 接着把 SYN 和 ACK 标志位置为 1。最后把该报文发给客户端 该报文也不包含应用层数据之后服务端处于 SYN-RCVD 状态。 4.客户端收到服务端报文后还要向服务端回应最后一个应答报文首先该应答报文 TCP 首部 ACK 标志位置为 1 其次「确认应答号」字段填入 server_isn 1 最后把报文发送给服务端 这次报文可以携带客户到服务端的数据之后客户端处于 ESTABLISHED 状态 5.服务端收到客户端的应答报文后也进入 ESTABLISHED 状态
第三次握手是可以携带数据的前两次握手是不可以携带数据的
2.为什么是三次握手不是两次、四次
1.三次握手才可以阻止重复历史连接的初始化主要原因 如果采用两次握手建立 TCP 连接的场景下服务端在向客户端发送数据前并没有阻止掉历史连接导致服务端建立了一个历史连接又白白发送了数据妥妥地浪费了服务端的资源 2.三次握手才可以同步双方的初始序列号 两次握手只保证了一方的初始序列号能被对方成功接收没办法保证双方的初始序列号都能被确认接收 3.三次握手才可以避免资源浪费 由于没有第三次握手服务端不清楚客户端是否收到了自己回复的 ACK 报文所以服务端每收到一个 SYN 就只能先主动建立一个连接这会造成什么情况呢 如果客户端发送的 SYN 报文在网络中阻塞了重复发送多次 SYN 报文那么服务端在收到请求后就会建立多个冗余的无效链接造成不必要的资源浪费 TCP 建立连接时通过三次握手能防止历史连接的建立能减少双方不必要的资源开销能帮助双方同步初始化序列号。序列号能够保证数据包不重复、不丢弃和按序传输。
不使用「两次握手」和「四次握手」的原因
1.「两次握手」无法防止历史连接的建立会造成双方资源的浪费也无法可靠的同步双方序列号 2.「四次握手」三次握手就已经理论上最少可靠连接建立所以不需要使用更多的通信次数。
3.为什么每次建立 TCP 连接时初始化的序列号都要求不一样呢
主要原因有两个方面 1.为了防止历史报文被下一个相同四元组的连接接收主要方面 2.为了安全性防止黑客伪造的相同序列号的 TCP 报文被对方接收 如果每次建立连接客户端和服务端的初始化序列号都是一样的话就有大概率遇到历史报文的序列号刚「好在」对方的接收窗口内从而导致历史报文被新连接成功接收。
每次初始化序列号不一样很大程度上能够避免历史报文被下一个相同四元组的连接接收 是很大程度上并不是完全避免了因为序列号会有回绕的问题所以需要用时间戳的机制来判断历史报文
4.初始序列号 ISN 是如何随机产生的
初始化序列号 ISN 随机生成算法ISN M F(localhost, localport, remotehost, remoteport)。
1.M 是一个计时器这个计时器每隔 4 微秒加 1。 2.F 是一个 Hash 算法根据源 IP、目的 IP、源端口、目的端口生成一个随机数值。 要保证 Hash 算法不能被外部轻易推算得出用 MD5 算法是一个比较好的选择。
随机数是会基于时钟计时器递增的基本不可能会随机成一样的初始化序列号
5.既然 IP 层会分片为什么 TCP 层还需要 MSS 呢
MTU一个网络包的最大长度以太网中一般为 1500 字节 MSS除去 IP 和 TCP 头部之后一个网络包所能容纳的 TCP 数据的最大长度
果一个 IP 分片丢失整个 IP 报文的所有分片都得重传 当某一个 IP 分片丢失后接收方的 IP 层就无法组装成一个完整的 TCP 报文头部 数据也就无法将数据报文送到 TCP 层所以接收方不会响应 ACK 给发送方因为发送方迟迟收不到 ACK 确认报文所以会触发超时重传就会重发「整个 TCP 报文头部 数据」 6.第一次握手丢失了会发生什么
1.当客户端想和服务端建立 TCP 连接的时候首先第一个发的就是 SYN 报文然后进入到 SYN_SENT 状态。
2.在这之后如果客户端迟迟收不到服务端的 SYN-ACK 报文第二次握手就会触发「超时重传」机制重传 SYN 报文而且重传的 SYN 报文的序列号都是一样的
客户端的 SYN 报文最大重传次数由 tcp_syn_retries内核参数控制这个参数是可以自定义的默认值一般是 5。
当第五次超时重传后会继续等待 32 秒每次超时的时间是上一次的 2 倍如果服务端仍然没有回应 ACK客户端就不再发送 SYN 包然后断开 TCP 连接
7.第二次握手丢失了会发生什么
第二次握手的 SYN-ACK 报文其实有两个目的 第二次握手里的 ACK 是对第一次握手的确认报文 第二次握手里的 SYN是服务端发起建立 TCP 连接的报文; 1.如果客户端迟迟没有收到第二次握手那么客户端就觉得可能自己的 SYN 报文第一次握手丢失了于是客户端就会触发超时重传机制重传 SYN 报文。 2.如果第二次握手丢失了服务端就收不到第三次握手于是服务端这边会触发超时重传机制重传 SYN-ACK 报文
因此当第二次握手丢失了客户端和服务端都会重传
1.客户端会重传 SYN 报文也就是第一次握手最大重传次数由 tcp_syn_retries内核参数决定 2.服务端会重传 SYN-ACK 报文也就是第二次握手最大重传次数由 tcp_synack_retries 内核参数决定
8.第三次握手丢失了会发生什么
第三次握手的 ACK 是对第二次握手的 SYN 的确认报文
所以当第三次握手丢失了如果服务端那一方迟迟收不到这个确认报文就会触发超时重传机制重传 SYN-ACK 报文直到收到第三次握手或者达到最大重传次数。
ACK 报文是不会有重传的当 ACK 丢失了就由对方重传对应的报文
9.什么是 SYN 攻击如何避免 SYN 攻击 在 TCP 三次握手的时候Linux 内核会维护两个队列分别是 1.半连接队列也称 SYN 队列 2.全连接队列也称 accept 队列 SYN攻击 攻击者短时间伪造不同 IP 地址的 SYN 报文服务端每接收到一个 SYN 报文就进入SYN_RCVD 状态但服务端发送出去的 ACK SYN 报文无法得到未知 IP 主机的 ACK 应答久而久之就会占满服务端的半连接队列使得服务端不能为正常用户服务
正常流程
1.当服务端接收到客户端的 SYN 报文时会创建一个半连接的对象然后将其加入到内核的「 SYN 队列」 2.接着发送 SYN ACK 给客户端等待客户端回应 ACK 报文 3.服务端接收到 ACK 报文后从「 SYN 队列」取出一个半连接对象然后创建一个新的连接对象放入到「 Accept 队列」 4.应用通过调用 accpet() socket 接口从「 Accept 队列」取出连接对象 SYN 攻击方式最直接的表现就会把 TCP 半连接队列打满这样当 TCP 半连接队列满了后续再在收到 SYN 报文就会丢弃导致客户端无法和服务端建立连接 不管是半连接队列还是全连接队列都有最大长度限制超过限制时默认情况都会丢弃报文 避免 SYN 攻击方式可以有以下四种方法
1.调大 netdev_max_backlog 2.增大 TCP 半连接队列 3.开启 tcp_syncookies 4.减少 SYNACK 重传次数
方式一调大 netdev_max_backlog
当网卡接收数据包的速度大于内核处理的速度时会有一个队列保存这些数据包。控制该队列的最大值如下参数默认值是 1000我们要适当调大该参数的值比如设置为 10000
net.core.netdev_max_backlog 10000方式二增大 TCP 半连接队列
方式三开启 net.ipv4.tcp_syncookies net.ipv4.tcp_syncookies 参数主要有以下三个值 0 值表示关闭该功能 1 值表示仅当 SYN 半连接队列放不下时再启用它 2 值表示无条件开启功能 那么在应对 SYN 攻击时只需要设置为 1 即可 方式四减少 SYNACK 重传次数 减少 SYN-ACK 的重传次数以加快处于 SYN_REVC 状态的 TCP 连接断开。