2018年09月19日 19:10:58 萧萧冷 阅读数:4332
版权声明:本文为博主学习笔记, 注明来源情况下随意转载 https://blog.csdn.net/lengxiao1993/article/details/82771768
Why do we need a 3-way handshake? Why not just 2-way
首先需要声明的是, 百度搜索到的大部分网络博客关于这个问题的解答都是不清晰或者不准确的。 讨论这个问题的大部分博客都会引用《计算机网络》的内容:
不幸的是, 这种解释是不准确的, TCP 采用三次握手的原因其实非常简单, 远没有大部分博客所描述的那样云山雾绕。
这里先给出结论:
- 为了实现可靠数据传输, TCP 协议的通信双方, 都必须维护一个序列号, 以标识发送出去的数据包中, 哪些是已经被对方收到的。 三次握手的过程即是通信双方相互告知序列号起始值, 并确认对方已经收到了序列号起始值的必经步骤
- 如果只是两次握手, 至多只有连接发起方的起始序列号能被确认, 另一方选择的序列号则得不到确认
TCP 的通信流程
上图中的每一个箭头都代表着一次 TCP数据包的发送
TCP 数据包结构图
在解答为什么 TCP 需要三次握手, 而不是两次之前, 首先需要回答的问题是:
如果读者对比一下 UDP 的通信流程和 TCP 的通信流程, 可以发现, 在 UDP 协议中, 是没有握手这个操作的。
这里就引出了 TCP 与 UDP 的一个基本区别, TCP 是可靠通信协议, 而 UDP 是不可靠通信协议。
UDP 和 TCP 协议都是基于同样的互联网基础设施, 且都基于 IP 协议实现, 互联网基础设施中对于数据包的发送过程是会发生丢包现象的, 为什么 TCP 就可以实现可靠传输, 而 UDP 不行?
TCP 协议为了实现可靠传输, 通信双方需要判断自己已经发送的数据包是否都被接收方收到, 如果没收到, 就需要重发。 为了实现这个需求, 很自然地就会引出序号(sequence number) 和 确认号(acknowledgement number)的使用。
发送方在发送数据包(假设大小为 10 byte)时, 同时送上一个序号( 假设为 500),那么接收方收到这个数据包以后, 就可以回复一个确认号(510 = 500 + 10) 告诉发送方 “我已经收到了你的数据包, 你可以发送下一个数据包, 序号从 510 开始” 。
这样发送方就可以知道哪些数据被接收到,哪些数据没被接收到, 需要重发。
正如上文所描述的,为了实现可靠传输,发送方和接收方始终需要同步( SYNchronize )序号。 需要注意的是, 序号并不是从 0 开始的, 而是由发送方随机选择的初始序列号 ( Initial Sequence Number, ISN )开始 。 由于 TCP 是一个双向通信协议, 通信双方都有能力发送信息, 并接收响应。 因此, 通信双方都需要随机产生一个初始的序列号, 并且把这个起始值告诉对方。
下面这个流程图描述的和上面一样, 但是更加清楚的展示了 TCP 数据包标志位, 以及数据域的命名来源。
AliceBobSYN =1 , seq = xSYNchronize withmy InitialSequence Numberof xSYN =1, ACK = 1, seq = y , ack = x+1I received yourISN, IACKnowledge thatI am ready for[x+1]SYNchronize withmy InitialSequence Numberof yACK =1 , seq = x+1, ack = y+1I received yoursyn, IACKnowledge thatI am ready for[y+1]AliceBob
原文:
https://blog.csdn.net/lengxiao1993/article/details/82771768
总来的说就是:
1:由于 TCP 是一个双向通信协议, 通信双方都有能力发送信息, 并接收响应。 因此, 通信双方都需要随机产生一个初始的序列号, 并且把这个起始值告诉对方。
2:同步序号
3:两次的话只有客户端的序号被确认了,服务器端的序号没有被确认。
4:tcp是可靠的面向连接的传输方式,但是如何保证这种方式呢,那就是通过同步一个序列号来就行的,通过这个序列号
可以实现重复数据刷掉,以及丢包重发的功能,保证了数据的完整性和数据传输的可靠性,以及数据包之间的有序性。
5:但是这种功能的实现依赖于syn(synchronize sequece number) ,可以理解成一个1个1位的数据包,专门用于同步序列号的。
也就是说如果客户端要与服务端建立连接都要发送syn,然而根据tcp建立连接的方式:
客户端在发送一个连接请求的时候(syn)服务端会发送一个确认信号,这是还需要客户端继续发送一个确认信号,但是如果这个时候客户端不发送确认信号,服务端会在限制时间内继续发送确认信号,这样会大大的消耗服务器资源,
那么怎么解决这方面的问题呢:
关于SYN攻击防范技术,人们研究得比较早。归纳起来,主要有两大类,一类是通过防火墙、路由器等过滤网关防护,另一类是通过加固TCP/IP协议栈防范
在“开始->运行->键入regedit”
启用 SYN 攻击保护的命名值位于注册表项 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\Tcpip\Parameters之下。值名称:SynAttackProtect。推荐值:2。
以下部分中的所有项和值均位于注册表项 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\Tcpip\Parameters 之下。
指定必须在触发 SYN flood 保护之前超过的 TCP 连接请求阈值。值名称:TcpMaxPortsExhausted。推荐值:5。
启用 SynAttackProtect 后,该值指定 SYN_RCVD 状态中的 TCP 连接阈值,超过 SynAttackProtect 时,触发 SYN flood 保护。值名称:TcpMaxHalfOpen。推荐值数据:500。
启用 SynAttackProtect 后,指定至少发送了一次重传的 SYN_RCVD 状态中的 TCP 连接阈值。超过 SynAttackProtect 时,触发 SYN flood 保护。值名称:TcpMaxHalfOpenRetried。推荐值数据:400
不难看出syn攻击时消耗大量带宽资源,所以要想防御syn洪水攻击,一个丰富的带宽资源是非常有必要的,通常的流量攻击,攻击者也是利用肉鸡的带宽资源来堵死目标网络的,所以这个也是一个重要的防御前提。
利用防火墙来进行防护攻击是目前最有效的方法,当然前提是攻击在防护带宽范围之内,也就是为什么第二条推荐带宽资源,这是保证在防火墙前面不会造成堵塞,来达到防火墙的防护目的。 [1]
来源百度百科