一、TCP握手流程

二、为什么不是4次握手

TCP的每次请求都是成对的,原则上应该是四次

  1. 【Client to Server】第一次SYN,seq=x
  2. 【Server to Client】第二次ACK,seq=y,ack=x+1(没有携带数据的ACK不消耗序列号)
  3. 【Server to Client】第三次SYN,seq=y,
  4. 【Client to Server】第四次ACK,seq=x+1,ack=y+1.

可以看出第二次和第三次都是Server to Client,且他们之间没有任何事件发生,所以可以合并,不是四次的原因是2,3步骤合并,增加效率。

三、为什么需要握手(为什么需要三《”四“》次握手)

要回答为什么先看看什么是TCP链接。ref https://tools.ietf.org/html/rfc793

    The reliability and flow control mechanisms described above requirez
that TCPs initialize and maintain certain status information for
each data stream. The combination of this information, including
sockets, sequence numbers, and window sizes, is called a connection.
Each connection is uniquely specified by a pair of sockets
identifying its two sides.

为了保证可靠性传输,TCP需要两边维护socket,序列号,和窗口大小(流量控制用),握手就是为了在数据开始传输前让客户端和服务器准确无误的交换上述信息。

需要握手的原因:

  1. 阻止已经失效的历史请求的初始化【谢希仁】
  2. 只有通过三次握手才能交换序列号

3.1 阻止已经失效的历史请求的初始化

ref:https://tools.ietf.org/html/rfc793

The principle reason for the three-way handshake is to 
prevent old duplicate connection initiations from causing confusion.

假如只有两次握手

假如服务端在ack以后就建立了链接,当有延迟的数据在链接关闭后到达服务端,

  • 服务端不知道这是旧链接,直接建立返回ack,且建立了链接。
  • 因为上一次链接已经关闭,客户端不认识这个ack,直接丢弃。

这样会导致服务端资源被这种失效的链接给浪费。

3.2 只有通过三次握手才能交换序列号

序列号是可靠性传输的根本,通过序列号,接收方可以去重,可以保证TCP流按照顺序最终被接受。

初始序列号是随机生成的(为了安全),所以在链接建立之初需要双方通过SYN来告知对方自己的初始序列号。

同时每一个发出去的序列号,都需要一个接收方的ACK,来告诉发送方:我已经收到了--可靠性保证

所以两次握手不行:服务端的SYN,没有办法ACK。

由于第二次和第三次可以合并,所以最终把逻辑上的四次握手变成了三次。

最新文章

  1. Hangfire入门(任务调度)
  2. ajax请求cookie有效性问题验证
  3. 将图片压缩后转Base64函数
  4. canvas时钟
  5. Nutch搜索引擎(第4期)_ Eclipse开发配置
  6. STM32 串口功能 库函数 详解和DMA 串口高级运用(转载)
  7. C 语言统计关键字出现次数
  8. Java基础篇Socket网络编程中的应用实例
  9. YSlow---基于firebug的插件 ,用于网站页面性能的分析
  10. nginx把POST转GET请求解决405问题
  11. 一大波开发者福利来了,一份微软官方Github上发布的开源项目清单等你签收
  12. linux tomcat单机部署多应用
  13. 小白的python之路Linux部分10/28&29
  14. selenium中的上传文件
  15. Spark学习之路 (十八)SparkSQL简单使用
  16. #Weex与Android交互(一)
  17. terminal record & gif
  18. Centos 7和 Centos 6开放查看端口 防火墙关闭打开
  19. ajax与302响应
  20. hibernate通过SQL更新数据

热门文章

  1. Tkinter经典写法
  2. Python os.chflags() 方法
  3. react-router分析 - 一、history
  4. 面试题:JVM 堆内存溢出后,其他线程是否可继续工作?
  5. FreeSql增加新特性Context
  6. adb如何连接Mac版腾讯手游助手
  7. 在图像中隐藏数据:用 Python 来实现图像隐写术
  8. 4、Java基本数据类型
  9. 论文结果图:matplotlib和seaborn实现
  10. troubleshoot之:用control+break解决线程死锁问题