TCP 协议

本贴最后更新于 2724 天前,其中的信息可能已经东海扬尘

TCP:可靠传输、按序到达。

一、TCP 报文段格式
源端口号(2byte)、目的端口号(2byte)
序列号(4byte)
ACKnum(4byte)
Offset(4bit)、Reserved(4bit)、TCP Flags(1byte)、Window(2byte)
Checksum(2byte)、...
...

二、三次握手

  1. 客户端向服务器发送连接建立请求报文段(Segement)(SYN=1,seq=x)(调用了 connect()方法),发送之后客户端进入 SYN_SEND 状态;
  2. 服务器收到客户端的请求报文段,向客户端发送一个 ACK 和连接建立请求结合在一起的报文段(ACK=1,ACKnum=x+1,SYN=1,seq=y),并从 LISTEN 状态(调用了 listen()方法)进入 SYN_RCVD 状态;
  3. 客户端收到 ACK 报文段后,向服务器发送一个 ACK 报文段(ACK=1,ACKnum=y+1),并进入 ESTABLISHED 状态;
  4. 服务器收到 ACK 报文段,也进入 ESTABLISHED 状态。
    至此,客户端和服务器的连接建立,之后就可以调用 read()和 write()方法进行读写操作了。

三、四次挥手

  1. 客户端向服务器发送连接关闭请求报文段(FIN=1,seq=x)(调用了 close()方法),发送之后客户端进入 FIN_WAIT_1 状态;
  2. 服务器收到客户端的请求报文段,向客户端发送 ACK 报文段(ACK=1,ACKnum=x+1),并进入 CLOSE_WAIT 状态;
  3. 客户端收到服务器的 ACK 报文段后进入 FIN_WAIT_2 状态;
  4. 服务器向客户端发送连接关闭请求报文段(FIN=1,seq=y)(调用了 close()方法),发送之后服务器进入 LAST_ACK 状态;
  5. 客户端收到服务器的请求报文段,向服务器发送 ACK 报文段(ACK=1,ACKnum=y+1),并进入 TIME_WAIT 状态;
  6. 服务器收到客户端的 ACK 报文段,进入 CLOSE 状态;
  7. 客户端等待 2MSL,期间没有收到服务端的连接关闭请求博爱文段,则进入 CLOSE 状态。
    至此,客户端与服务器的连接关闭。

MSL(Maxinum Segment Live)
TCP 报文在网络传输时最长生存时间。

客户端为什么要等待 2MSL
因为 ACK 报文段可能在网络传输的过程中丢失。如果发送了这种情况,那么服务器在等待 2MSL 时间后会重新一个连接关闭请求报文段,客户端在等待的这 2MSL 时间内正好可以收到这个请求报文段,于是重发 ACK 报文段,再等待 2MSL,重复这个过程直到在等待的 2MSL 时间内没有收到请求报文段,进入 CLOSE 状态。

SYN Flood 攻击
描述:给服务器发了一个 SYN 后,就下线了,于是服务器需要默认等 63s 才会断开连接,这样,攻击者就可以把服务器的 syn 连接的队列耗尽,让正常的连接请求不能处理。
解决方法:Linux 下给了一个叫 tcp_syncookies 的参数来应对这个事——当 SYN 队列满了后,TCP 会通过源地址端口、目标地址端口和时间戳打造出一个特别的 Sequence Number 发回去(又叫 cookie),如果是攻击者则不会有响应,如果是正常连接,则会把这个 SYN Cookie 发回来,然后服务端可以通过 cookie 建连接(即使你不在 SYN 队列中)。

三、确认机制
一种是确认收到的最大的连续收到的包。
一种是收到一个包去人一个包。

四、超时重传机制
一种是重传超时的包及其之后的包(因为接收端只确认了最大的连续收到的包),快,但浪费带宽。
一种是仅重传超时的包,慢,但节省带宽。

往返时间(RTT,Round Trip Time)
通过 RTT+ 算法(好几种)算出超时重传时间(RTO,Retransmission TimeOut)。

五、滑动窗口协议
window:还有多少缓冲区可以用。

发送端
LastByteAcked、LastByteSent、LastByteWriter
SendWindow、UsableWindow

接收器
LastByteRead、NextByteExpected、LastByteRcvd
...、ReceiveWindow
window=MaxRcvBuffer - LastByteRcvd – 1

六、拥塞控制
慢启动阈值(ssthresh,slow start threshold)

拥塞控制算法:
Tahoe:没有快速恢复阶段;
Reno:增加了快速恢复阶段。

1. 慢启动
拥塞窗口(cwnd,Congestion Window)。
①. 连接建立后初始化 cwnd=1;
②. 每当收到一个 ACK,cwnd++,呈线性上升;
③. 每过一个 RTT,cwnd*=2,呈指数上升;
④. 当 cwnd>=慢启动阈值时,将 cwnd 减半,进入拥塞避免算法;

2. 拥塞避免
①. 每收到一个 ACK,cwnd = cwnd + 1/cwnd;
②. 每过一个 RTT,cwnd += 1;

3. 快速重传
收到 3 个重复 ACK 就重传包,然后 cwnd = cwnd /2,ssthresh = cwnd, 进入快速恢复阶段。
(以前是等到超过超时重传时间 RTO 再重传包,然后 ssthresh = cwnd /2,cwnd 置为 1,重新进入慢启动。)

4. 快速恢复
快速恢复阶段认为,还有 3 个重复 ACK 说明网络并不那么糟糕,所以
①. cwnd = ssthresh + 3*MSS;
②. 重传重复 ACK 指定的包;
③. 如果再收到重复 ACK,直接 cwnd += 1;
④. 如果收到新的 ACK,那么 cwnd = ssthresh,然后进入拥塞避免算法。

这个快速恢复算法存在的问题就是它依赖于 3 个重复的 ACK。 注意,3 个重复的 ACK 并不代表只丢了一个数据包,很有可能是丢了好多包。但这个算法只会重传一个,而剩下的那些包只能等到 RTO 超时,于是,进入了恶 梦模式——超时一个窗口就减半一下,多个超时会超成 TCP 的传输速度呈级数下降,而且也不会触发快速恢复算法了。

相关帖子

回帖

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • Access
    1 引用 • 3 回帖 • 1 关注
  • Scala

    Scala 是一门多范式的编程语言,集成面向对象编程和函数式编程的各种特性。

    13 引用 • 11 回帖 • 159 关注
  • FreeMarker

    FreeMarker 是一款好用且功能强大的 Java 模版引擎。

    23 引用 • 20 回帖 • 467 关注
  • 深度学习

    深度学习(Deep Learning)是机器学习的分支,是一种试图使用包含复杂结构或由多重非线性变换构成的多个处理层对数据进行高层抽象的算法。

    54 引用 • 44 回帖
  • 30Seconds

    📙 前端知识精选集,包含 HTML、CSS、JavaScript、React、Node、安全等方面,每天仅需 30 秒。

    • 精选常见面试题,帮助您准备下一次面试
    • 精选常见交互,帮助您拥有简洁酷炫的站点
    • 精选有用的 React 片段,帮助你获取最佳实践
    • 精选常见代码集,帮助您提高打码效率
    • 整理前端界的最新资讯,邀您一同探索新世界
    488 引用 • 384 回帖 • 9 关注
  • Jenkins

    Jenkins 是一套开源的持续集成工具。它提供了非常丰富的插件,让构建、部署、自动化集成项目变得简单易用。

    54 引用 • 37 回帖 • 1 关注
  • 职场

    找到自己的位置,萌新烦恼少。

    127 引用 • 1708 回帖
  • Quicker

    Quicker 您的指尖工具箱!操作更少,收获更多!

    37 引用 • 157 回帖
  • JetBrains

    JetBrains 是一家捷克的软件开发公司,该公司位于捷克的布拉格,并在俄国的圣彼得堡及美国麻州波士顿都设有办公室,该公司最为人所熟知的产品是 Java 编程语言开发撰写时所用的集成开发环境:IntelliJ IDEA

    18 引用 • 54 回帖 • 1 关注
  • SVN

    SVN 是 Subversion 的简称,是一个开放源代码的版本控制系统,相较于 RCS、CVS,它采用了分支管理系统,它的设计目标就是取代 CVS。

    29 引用 • 98 回帖 • 688 关注
  • Swagger

    Swagger 是一款非常流行的 API 开发工具,它遵循 OpenAPI Specification(这是一种通用的、和编程语言无关的 API 描述规范)。Swagger 贯穿整个 API 生命周期,如 API 的设计、编写文档、测试和部署。

    26 引用 • 35 回帖
  • Mobi.css

    Mobi.css is a lightweight, flexible CSS framework that focus on mobile.

    1 引用 • 6 回帖 • 760 关注
  • SQLServer

    SQL Server 是由 [微软] 开发和推广的关系数据库管理系统(DBMS),它最初是由 微软、Sybase 和 Ashton-Tate 三家公司共同开发的,并于 1988 年推出了第一个 OS/2 版本。

    21 引用 • 31 回帖 • 3 关注
  • Q&A

    提问之前请先看《提问的智慧》,好的问题比好的答案更有价值。

    9768 引用 • 44440 回帖 • 88 关注
  • Kotlin

    Kotlin 是一种在 Java 虚拟机上运行的静态类型编程语言,由 JetBrains 设计开发并开源。Kotlin 可以编译成 Java 字节码,也可以编译成 JavaScript,方便在没有 JVM 的设备上运行。在 Google I/O 2017 中,Google 宣布 Kotlin 成为 Android 官方开发语言。

    19 引用 • 33 回帖 • 74 关注
  • MyBatis

    MyBatis 本是 Apache 软件基金会 的一个开源项目 iBatis,2010 年这个项目由 Apache 软件基金会迁移到了 google code,并且改名为 MyBatis ,2013 年 11 月再次迁移到了 GitHub。

    173 引用 • 414 回帖 • 364 关注
  • Elasticsearch

    Elasticsearch 是一个基于 Lucene 的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于 RESTful 接口。Elasticsearch 是用 Java 开发的,并作为 Apache 许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。

    117 引用 • 99 回帖 • 200 关注
  • GitLab

    GitLab 是利用 Ruby 一个开源的版本管理系统,实现一个自托管的 Git 项目仓库,可通过 Web 界面操作公开或私有项目。

    46 引用 • 72 回帖 • 1 关注
  • RESTful

    一种软件架构设计风格而不是标准,提供了一组设计原则和约束条件,主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

    30 引用 • 114 回帖 • 6 关注
  • jsDelivr

    jsDelivr 是一个开源的 CDN 服务,可为 npm 包、GitHub 仓库提供免费、快速并且可靠的全球 CDN 加速服务。

    5 引用 • 31 回帖 • 110 关注
  • 机器学习

    机器学习(Machine Learning)是一门多领域交叉学科,涉及概率论、统计学、逼近论、凸分析、算法复杂度理论等多门学科。专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能。

    83 引用 • 37 回帖
  • 新人

    让我们欢迎这对新人。哦,不好意思说错了,让我们欢迎这位新人!
    新手上路,请谨慎驾驶!

    52 引用 • 228 回帖
  • 架构

    我们平时所说的“架构”主要是指软件架构,这是有关软件整体结构与组件的抽象描述,用于指导软件系统各个方面的设计。另外还有“业务架构”、“网络架构”、“硬件架构”等细分领域。

    143 引用 • 442 回帖 • 2 关注
  • 快应用

    快应用 是基于手机硬件平台的新型应用形态;标准是由主流手机厂商组成的快应用联盟联合制定;快应用标准的诞生将在研发接口、能力接入、开发者服务等层面建设标准平台;以平台化的生态模式对个人开发者和企业开发者全品类开放。

    15 引用 • 127 回帖 • 2 关注
  • API

    应用程序编程接口(Application Programming Interface)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。

    79 引用 • 431 回帖
  • Latke

    Latke 是一款以 JSON 为主的 Java Web 框架。

    71 引用 • 535 回帖 • 832 关注
  • 区块链

    区块链是分布式数据存储、点对点传输、共识机制、加密算法等计算机技术的新型应用模式。所谓共识机制是区块链系统中实现不同节点之间建立信任、获取权益的数学算法 。

    92 引用 • 752 回帖