当前位置: 首页 > news >正文

个人网站源码免费下载网页设计策划书ppt

个人网站源码免费下载,网页设计策划书ppt,活动策划书模板范文,h5制作成品我们本篇文章的组织脉络如下运输层位于应用层和网络层之间#xff0c;是 OSI 分层体系中的第四层#xff0c;同时也是网络体系结构的重要部分。运输层主要负责网络上的端到端通信。运输层为运行在不同主机上的应用程序之间的通信起着至关重要的作用。下面我们就来一起探讨一下… 我们本篇文章的组织脉络如下运输层位于应用层和网络层之间是 OSI 分层体系中的第四层同时也是网络体系结构的重要部分。运输层主要负责网络上的端到端通信。运输层为运行在不同主机上的应用程序之间的通信起着至关重要的作用。下面我们就来一起探讨一下关于运输层的协议部分运输层概述计算机网络的运输层非常类似于高速公路高速公路负责把人或者物品从一端运送到另一端而计算机网络的运输层则负责把报文从一端运输到另一端这个端指的就是 端系统。在计算机网络中任意一个可以交换信息的介质都可以称为端系统比如手机、网络媒体、电脑、运营商等。在运输层运输报文的过程中会遵守一定的协议规范比如一次传输的数据限制、选择什么样的运输协议等。运输层实现了让两个互不相关的主机进行逻辑通信的功能看起来像是让两个主机相连一样。运输层协议是在端系统中实现的而不是在路由器中实现的。路由只是做识别地址并转发的功能。这就比如快递员送快递一样当然是要由地址的接受人也就是 xxx 号楼 xxx 单元 xxx 室的这个人来判断了TCP 如何判断是哪个端口的呢还记得数据包的结构吗这里来回顾一下数据包经过每层后该层协议都会在数据包附上包首部一个完整的包首部图如上所示。在数据传输到运输层后会为其附上 TCP 首部首部包含着源端口号和目的端口号。在发送端运输层将从发送应用程序进程接收到的报文转化成运输层分组分组在计算机网络中也称为 报文段(segment)。运输层一般会将报文段进行分割分割成为较小的块为每一块加上运输层首部并将其向目的地发送。在发送过程中可选的运输层协议(也就是交通工具) 主要有 TCP 和 UDP 关于这两种运输协议的选择及其特性也是我们着重探讨的重点。TCP 和 UDP 前置知识在 TCP/IP 协议中能够实现传输层功能的最具代表性的就是 TCP 和 UDP。提起 TCP 和 UDP 就得先从这两个协议的定义说起。TCP 叫做传输控制协议(TCPTransmission Control Protocol)通过名称可以大致知道 TCP 协议有控制传输的功能主要体现在其可控可控就表示着可靠确实是这样的TCP 为应用层提供了一种可靠的、面向连接的服务它能够将分组可靠的传输到服务端。UDP 叫做 用户数据报协议(UDPUser Datagram Protocol)通过名称可以知道 UDP 把重点放在了数据报上它为应用层提供了一种无需建立连接就可以直接发送数据报的方法。怎么计算机网络中的术语对一个数据的描述这么多啊在计算机网络中在不同层之间会有不同的描述。我们上面提到会将运输层的分组称为报文段除此之外还会将 TCP 中的分组也称为报文段然而将 UDP 的分组称为数据报同时也将网络层的分组称为数据报但是为了统一一般在计算机网络中我们统一称 TCP 和 UDP 的报文为 报文段这个就相当于是约定到底如何称呼不用过多纠结啦。套接字在 TCP 或者 UDP 发送具体的报文信息前需要先经过一扇 门这个门就是套接字(socket)套接字向上连接着应用层向下连接着网络层。在操作系统中操作系统分别为应用和硬件提供了接口(Application Programming Interface)。而在计算机网络中套接字同样是一种接口它也是有接口 API 的。使用 TCP 或 UDP 通信时会广泛用到套接字的 API使用这套 API 设置 IP 地址、端口号实现数据的发送和接收。现在我们知道了 Socket 和 TCP/IP 没有必然联系Socket 的出现只是方便了 TCP/IP 的使用如何方便使用呢你可以直接使用下面 Socket API 的这些方法。套接字类型套接字的主要类型有三种下面我们分别介绍一下数据报套接字(Datagram sockets)数据报套接字提供一种无连接的服务而且并不能保证数据传输的可靠性。数据有可能在传输过程中丢失或出现数据重复且无法保证顺序地接收到数据。数据报套接字使用UDP( User DatagramProtocol)协议进行数据的传输。由于数据报套接字不能保证数据传输的可靠性对于有可能出现的数据丢失情况需要在程序中做相应的处理。流套接字(Stream sockets)流套接字用于提供面向连接、可靠的数据传输服务。能够保证数据的可靠性、顺序性。流套接字之所以能够实现可靠的数据服务原因在于其使用了传输控制协议即 TCP(The Transmission Control Protocol)协议原始套接字(Raw sockets): 原始套接字允许直接发送和接收 IP 数据包而无需任何特定于协议的传输层格式原始套接字可以读写内核没有处理过的 IP 数据包。套接字处理过程在计算机网络中要想实现通信必须至少需要两个端系统至少需要一对两个套接字才行。下面是套接字的通信过程。socket 中的 API 用于创建通信链路中的端点创建完成后会返回描述该套接字的套接字描述符。就像使用文件描述符来访问文件一样套接字描述符用来访问套接字。当应用程序具有套接字描述符后它可以将唯一的名称绑定在套接字上服务器必须绑定一个名称才能在网络中访问在为服务端分配了 socket 并且将名称使用 bind 绑定到套接字上后将会调用 listen api。listen 表示客户端愿意等待连接的意愿listen 必须在 accept api 之前调用。客户端应用程序在流套接字(基于 TCP)上调用 connect 发起与服务器的连接请求。服务器应用程序使用acceptAPI 接受客户端连接请求服务器必须先成功调用 bind 和 listen 后再调用 accept api。在流套接字之间建立连接后客户端和服务器就可以发起 read/write api 调用了。当服务器或客户端要停止操作时就会调用 close API 释放套接字获取的所有系统资源。虽然套接字 API 位于应用程序层和传输层之间的通信模型中但是套接字 API 不属于通信模型。套接字 API 允许应用程序与传输层和网络层进行交互。在往下继续聊之前我们先播放一个小插曲简单聊一聊 IP。聊聊 IPIP 是Internet Protocol网际互连协议的缩写是 TCP/IP 体系中的网络层协议。设计 IP 的初衷主要想解决两类问题提高网络扩展性实现大规模网络互联对应用层和链路层进行解藕让二者独立发展。IP 是整个 TCP/IP 协议族的核心也是构成互联网的基础。为了实现大规模网络的互通互联IP 更加注重适应性、简洁性和可操作性并在可靠性做了一定的牺牲。IP 不保证分组的交付时限和可靠性所传送分组有可能出现丢失、重复、延迟或乱序等问题。我们知道TCP 协议的下一层就是 IP 协议层既然 IP 不可靠那么如何保证数据能够准确无误地到达呢这就涉及到 TCP 传输机制的问题了我们后面聊到 TCP 的时候再说。端口号在聊端口号前先来聊一聊文件描述以及 socket 和端口号的关系为了方便资源的使用提高机器的性能、利用率和稳定性等等原因我们的计算机都有一层软件叫做操作系统它用于帮我们管理计算机可以使用的资源当我们的程序要使用一个资源的时候可以向操作系统申请再由操作系统为我们的程序分配和管理资源。通常当我们要访问一个内核设备或文件时程序可以调用系统函数系统就会为我们打开设备或文件然后返回一个文件描述符fd或称为ID是一个整数我们要访问该设备或文件只能通过该文件描述符。可以认为该编号对应着打开的文件或设备。而当我们的程序要使用网络时要使用到对应的操作系统内核的操作和网卡设备所以我们可以向操作系统申请然后系统会为我们创建一个套接字 Socket并返回这个 Socket 的ID以后我们的程序要使用网络资源只要向这个 Socket 的编号 ID 操作即可。而我们的每一个网络通信的进程至少对应着一个 Socket。向 Socket 的 ID 中写数据相当于向网络发送数据向 Socket 中读数据相当于接收数据。而且这些套接字都有唯一标识符——文件描述符 fd。端口号是 16 位的非负整数它的范围是 0 - 65535 之间这个范围会分为三种不同的端口号段由 Internet 号码分配机构 IANA 进行分配周知/标准端口号它的范围是 0 - 1023注册端口号范围是 1024 - 49151私有端口号范围是 49152 - 6553一台计算机上可以运行多个应用程序当一个报文段到达主机后应该传输给哪个应用程序呢你怎么知道这个报文段就是传递给 HTTP 服务器而不是 SSH 服务器的呢是凭借端口号吗当报文到达服务器时是端口号来区分不同应用程序的所以应该借助端口号来区分。举个例子反驳一下 cxuan假如到达服务器的两条数据都是由 80 端口发出的你该如何区分呢或者说到达服务器的两条数据端口一样协议不同该如何区分呢所以仅凭端口号来确定某一条报文显然是不够的。互联网上一般使用 源 IP 地址、目标 IP 地址、源端口号、目标端口号 来进行区分。如果其中的某一项不同就被认为是不同的报文段。这些也是多路分解和多路复用 的基础。确定端口号在实际通信之前需要先确定一下端口号确定端口号的方法分为两种标准既定的端口号标准既定的端口号是静态分配的每个程序都会有自己的端口号每个端口号都有不同的用途。端口号是一个 16 比特的数其大小在 0 - 65535 之间0 - 1023 范围内的端口号都是动态分配的既定端口号例如 HTTP 使用 80 端口来标识FTP 使用 21 端口来标识SSH 使用 22 来标识。这类端口号有一个特殊的名字叫做 周知端口号(Well-Known Port Number)。时序分配的端口号第二种分配端口号的方式是一种动态分配法在这种方法下客户端应用程序可以完全不用自己设置端口号凭借操作系统进行分配操作系统可以为每个应用程序分配互不冲突的端口号。这种动态分配端口号的机制即使是同一个客户端发起的 TCP 连接也能识别不同的连接。多路复用和多路分解我们上面聊到了在主机上的每个套接字都会分配一个端口号当报文段到达主机时运输层会检查报文段中的目的端口号并将其定向到相应的套接字然后报文段中的数据通过套接字进入其所连接的进程。下面我们来聊一下什么是多路复用和多路分解的概念。多路复用和多路分解分为两种即无连接的多路复用(多路分解)和面向连接的多路复用(多路分解)无连接的多路复用和多路分解开发人员会编写代码确定端口号是周知端口号还是时序分配的端口号。假如主机 A 中的一个 10637 端口要向主机 B 中的 45438 端口发送数据运输层采用的是 UDP 协议数据在应用层产生后会在运输层中加工处理然后在网络层将数据封装得到 IP 数据报IP 数据包通过链路层尽力而为的交付给主机 B然后主机 B 会检查报文段中的端口号判断是哪个套接字的这一系列的过程如下所示UDP 套接字就是一个二元组二元组包含目的 IP 地址和目的端口号。所以如果两个 UDP 报文段有不同的源 IP 地址和/或相同的源端口号但是具有相同的目的 IP 地址和目的端口号那么这两个报文会通过套接字定位到相同的目的进程。这里思考一个问题主机 A 给主机 B 发送一个消息为什么还需要知道源端口号呢比如我给妹子表达出我对你有点意思的信息妹子还需要知道这个信息是从我的哪个器官发出的吗知道是我这个人对你有点意思不就完了实际上是需要的因为妹子如果要表达出她对你也有点意思她是不是可能会亲你一口那她得知道往哪亲吧这就是在 A 到 B 的报文段中源端口号会作为 返回地址 的一部分即当 B 需要回发一个报文段给 A 时B 需要从 A 到 B 中的源端口号取值如下图所示面向连接的多路复用与多路分解如果说无连接的多路复用和多路分解指的是 UDP 的话那么面向连接的多路复用与多路分解指的是 TCP 了TCP 和 UDP 在报文结构上的差别是UDP 是一个二元组而 TCP 是一个四元组即源 IP 地址、目标 IP 地址、源端口号、目标端口号 这个我们上面也提到了。当一个 TCP 报文段从网络到达一台主机时这个主机会根据这四个值拆解到对应的套接字上。上图显示了面向连接的多路复用和多路分解的过程图中主机 C 向主机 B 发起了两个 HTTP 请求主机 A 向主机 C 发起了一个 HTTP 请求主机 A、B、C 都有自己唯一的 IP 地址当主机 C 发出 HTTP 请求后主机 B 能够分解这两个 HTTP 连接因为主机 C 发出请求的两个源端口号不同所以对于主机 B 来说这是两条请求主机 B 能够进行分解。对于主机 A 和主机 C 来说这两个主机有不同的 IP 地址所以对于主机 B 来说也能够进行分解。UDP终于我们开始了对 UDP 协议的探讨淦起UDP 的全称是 用户数据报协议(UDPUser Datagram Protocol)UDP 为应用程序提供了一种无需建立连接就可以发送封装的 IP 数据包的方法。如果应用程序开发人员选择的是 UDP 而不是 TCP 的话那么该应用程序相当于就是和 IP 直接打交道的。从应用程序传递过来的数据会附加上多路复用/多路分解的源和目的端口号字段以及其他字段然后将形成的报文传递给网络层网络层将运输层报文段封装到 IP 数据报中然后尽力而为的交付给目标主机。最关键的一点就是使用 UDP 协议在将数据报传递给目标主机时发送方和接收方的运输层实体间是没有握手的。正因为如此UDP 被称为是无连接的协议。UDP 特点UDP 协议一般作为流媒体应用、语音交流、视频会议所使用的传输层协议我们大家都知道的 DNS 协议底层也使用了 UDP 协议这些应用或协议之所以选择 UDP 主要是因为以下这几点速度快采用 UDP 协议时只要应用进程将数据传给 UDPUDP 就会将此数据打包进 UDP 报文段并立刻传递给网络层然后 TCP 有拥塞控制的功能它会在发送前判断互联网的拥堵情况如果互联网极度阻塞那么就会抑制 TCP 的发送方。使用 UDP 的目的就是希望实时性。无须建立连接TCP 在数据传输之前需要经过三次握手的操作而 UDP 则无须任何准备即可进行数据传输。因此 UDP 没有建立连接的时延。如果使用 TCP 和 UDP 来比喻开发人员TCP 就是那种凡事都要设计好没设计不会进行开发的工程师需要把一切因素考虑在内后再开干所以非常靠谱而 UDP 就是那种上来直接干干干接到项目需求马上就开干也不管设计也不管技术选型就是干这种开发人员非常不靠谱但是适合快速迭代开发因为可以马上上手无连接状态TCP 需要在端系统中维护连接状态连接状态包括接收和发送缓存、拥塞控制参数以及序号和确认号的参数在 UDP 中没有这些参数也没有发送缓存和接受缓存。因此某些专门用于某种特定应用的服务器当应用程序运行在 UDP 上一般能支持更多的活跃用户分组首部开销小每个 TCP 报文段都有 20 字节的首部开销而 UDP 仅仅只有 8 字节的开销。这里需要注意一点并不是所有使用 UDP 协议的应用层都是不可靠的应用程序可以自己实现可靠的数据传输通过增加确认和重传机制。所以使用 UDP 协议最大的特点就是速度快。UDP 报文结构下面来一起看一下 UDP 的报文结构每个 UDP 报文分为 UDP 报头和 UDP 数据区两部分。报头由 4 个 16 位长2 字节字段组成分别说明该报文的源端口、目的端口、报文长度和校验值。源端口号(Source Port) :这个字段占据 UDP 报文头的前 16 位通常包含发送数据报的应用程序所使用的 UDP 端口。接收端的应用程序利用这个字段的值作为发送响应的目的地址。这个字段是可选项有时不会设置源端口号。没有源端口号就默认为 0 通常用于不需要返回消息的通信中。目标端口号(Destination Port): 表示接收端端口字段长为 16 位长度(Length): 该字段占据 16 位表示 UDP 数据报长度包含 UDP 报文头和 UDP 数据长度。因为 UDP 报文头长度是 8 个字节所以这个值最小为 8最大长度为 65535 字节。校验和(Checksum)UDP 使用校验和来保证数据安全性UDP 的校验和也提供了差错检测功能差错检测用于校验报文段从源到目标主机的过程中数据的完整性是否发生了改变。发送方的 UDP 对报文段中的 16 比特字的和进行反码运算求和时遇到的位溢出都会被忽略比如下面这个例子三个 16 比特的数字进行相加这些 16 比特的前两个和是然后再将上面的结果和第三个 16 比特的数进行相加最后一次相加的位会进行溢出溢出位 1 要被舍弃然后进行反码运算反码运算就是将所有的 1 变为 0 0 变为 1。因此 1000 0100 1001 0101 的反码就是 0111 1011 0110 1010这就是校验和如果在接收方数据没有出现差错那么全部的 4 个 16 比特的数值进行运算同时也包括校验和如果最后结果的值不是 1111 1111 1111 1111 的话那么就表示传输过程中的数据出现了差错。下面来想一个问题为什么 UDP 会提供差错检测的功能这其实是一种 端到端 的设计原则这个原则说的是要让传输中各种错误发生的概率降低到一个可以接受的水平。文件从主机A传到主机B也就是说AB主机要通信需要经过三个环节首先是主机A从磁盘上读取文件并将数据分组成一个个数据包packet,然后数据包通过连接主机A和主机B的网络传输到主机B最后是主机B收到数据包并将数据包写入磁盘。在这个看似简单其实很复杂的过程中可能会由于某些原因而影响正常通信。比如磁盘上文件读写错误、缓冲溢出、内存出错、网络拥挤等等这些因素都有可能导致数据包的出错或者丢失由此可见用于通信的网络是不可靠的。由于实现通信只要经过上述三个环节那么我们就想是否在其中某个环节上增加一个检错纠错机制来用于对信息进行把关呢网络层肯定不能做这件事因为网络层的最主要目的是增大数据传输的速率网络层不需要考虑数据的完整性数据的完整性和正确性交给端系统去检测就行了因此在数据传输中对于网络层只能要求其提供尽可能好的数据传输服务而不可能寄希望于网络层提供数据完整性的服务。UDP 不可靠的原因是它虽然提供差错检测的功能但是对于差错没有恢复能力更不会有重传机制。TCPUDP 是一种没有复杂的控制提供无连接通信服务的一种协议换句话说它将部分控制部分交给应用程序去处理自己只提供作为传输层协议最基本的功能。而与 UDP 不同的是同样作为传输层协议TCP 协议要比 UDP 的功能多很多。TCP 的全称是 Transmission Control Protocol它被称为是一种面向连接(connection-oriented) 的协议这是因为一个应用程序开始向另一个应用程序发送数据之前这两个进程必须先进行握手握手是一个逻辑连接并不是两个主机之间进行真实的握手。这个连接是指各种设备、线路或者网络中进行通信的两个应用程序为了相互传递消息而专有的、虚拟的通信链路也叫做虚拟电路。一旦主机 A 和主机 B 建立了连接那么进行通信的应用程序只使用这个虚拟的通信线路发送和接收数据就可以保证数据的传输TCP 协议负责控制连接的建立、断开、保持等工作。TCP 连接是全双工服务(full-duplex service) 的全双工是什么意思全双工指的是主机 A 与另外一个主机 B 存在一条 TCP 连接那么应用程数据就可以从主机 B 流向主机 A 的同时也从主机 A 流向主机 B。TCP 只能进行 点对点(point-to-point) 连接那么所谓的多播即一个主机对多个接收方发送消息的情况是不存在的TCP 连接只能连接两个一对主机。TCP 的连接建立需要经过三次握手这个我们下面再说。一旦 TCP 连接建立后主机之间就可以相互发送数据了客户进程通过套接字传送数据流。数据一旦通过套接字后它就由客户中运行的 TCP 协议所控制。TCP 会将数据临时存储到连接的发送缓存(send buffer) 中这个 send buffer 是三次握手之间设置的缓存之一然后 TCP 在合适的时间将发送缓存中的数据发送到目标主机的接收缓存中实际上每一端都会有发送缓存和接收缓存如下所示主机之间的发送是以 报文段(segment) 进行的那么什么是 Segement 呢TCP 会将要传输的数据流分为多个块(chunk)然后向每个 chunk 中添加 TCP 标头这样就形成了一个 TCP 段也就是报文段。每一个报文段可以传输的长度是有限的不能超过最大数据长度(Maximum Segment Size)俗称 MSS。在报文段向下传输的过程中会经过链路层链路层有一个 Maximum Transmission Unit 最大传输单元 MTU 即数据链路层上所能通过最大数据包的大小最大传输单元通常与通信接口有关。那么 MSS 和 MTU 有啥关系呢因为计算机网络是分层考虑的这个很重要不同层的称呼不一样对于传输层来说称为报文段而对网络层来说就叫做 IP 数据包所以MTU 可以认为是网络层能够传输的最大 IP 数据包而 MSSMaximum segment size可以认为是传输层的概念也就是 TCP 数据包每次能够传输的最大量。TCP 报文段结构在简单聊了聊 TCP 连接后下面我们就来聊一下 TCP 的报文段结构如下图所示TCP 报文段结构相比 UDP 报文结构多了很多内容。但是前两个 32 比特的字段是一样的。它们是 源端口号 和 目标端口号我们知道这两个字段是用于多路复用和多路分解的。另外和 UDP 一样TCP 也包含校验和(checksum field) 除此之外TCP 报文段首部还有下面这些32 比特的序号字段(sequence number field) 和 32 比特的确认号字段(acknowledgment number field) 。这些字段被 TCP 发送方和接收方用来实现可靠的数据传输。4 比特的首部字段长度字段(header length field)这个字段指示了以 32 比特的字为单位的 TCP 首部长度。TCP 首部的长度是可变的但是通常情况下选项字段为空所以 TCP 首部字段的长度是 20 字节。16 比特的 接受窗口字段(receive window field) 这个字段用于流量控制。它用于指示接收方能够/愿意接受的字节数量可变的选项字段(options field)这个字段用于发送方和接收方协商最大报文长度也就是 MSS 时使用6 比特的 标志字段(flag field) ACK 标志用于指示确认字段中的值是有效的这个报文段包括一个对已被成功接收报文段的确认RST、SYN、FIN 标志用于连接的建立和关闭CWR 和 ECE 用于拥塞控制PSH 标志用于表示立刻将数据交给上层处理URG 标志用来表示数据中存在需要被上层处理的 紧急 数据。紧急数据最后一个字节由 16 比特的紧急数据指针字段(urgeent data pointer field) 指出。一般情况下PSH 和 URG 并没有使用。TCP 的各种功能和特点都是通过 TCP 报文结构来体现的在聊完 TCP 报文结构之后我们下面就来聊一下 TCP 有哪些功能及其特点了。序号、确认号实现传输可靠性TCP 报文段首部中两个最重要的字段就是 序号 和 确认号这两个字段是 TCP 实现可靠性的基础那么你肯定好奇如何实现可靠性呢要了解这一点首先我们得先知道这两个字段里面存了哪些内容吧一个报文段的序号就是数据流的字节编号 。因为 TCP 会把数据流分割成为一段一段的字节流因为字节流本身是有序的所以每一段的字节编号就是标示是哪一段的字节流。比如主机 A 要给主机 B 发送一条数据。数据经过应用层产生后会有一串数据流数据流会经过 TCP 分割分割的依据就是 MSS假设数据是 10000 字节MSS 是 2000 字节那么 TCP 就会把数据拆分成 0 - 1999 , 2000 - 3999 的段依次类推。所以第一个数据 0 - 1999 的首字节编号就是 0 2000 - 3999 的首字节编号就是 2000 。然后每个序号都会被填入 TCP 报文段首部的序号字段中。至于确认号的话会比序号要稍微麻烦一些。这里我们先拓展下几种通信模型。单工通信单工数据传输只支持数据在一个方向上传输在同一时间只有一方能接受或发送信息不能实现双向通信比如广播、电视等。双工通信是一种点对点系统由两个或者多个在两个方向上相互通信的连接方或者设备组成。双工通信模型有两种全双工(FDX)和半双工(HDX)全双工在全双工系统中连接双方可以相互通信一个最常见的例子就是电话通信。全双工通信是两个单工通信方式的结合它要求发送设备和接收设备都有独立的接收和发送能力。半双工在半双工系统中连接双方可以彼此通信但不能同时通信比如对讲机只有把按钮按住的人才能够讲话只有一个人讲完话后另外一个人才能讲话。单工、半双工、全双工通信如下图所示TCP 是一种全双工的通信协议因此主机 A 在向主机 B 发送消息的过程中也在接受来自主机 B 的数据。主机 A 填充进报文段的确认号是期望从主机 B 收到的下一字节的序号。稍微有点绕我们来举个例子看一下。比如主机 A 收到了来自主机 B 发送的编号为 0 - 999 字节的报文段这个报文段会写入序号中随后主机 A 期望能够从主机 B 收到 1000 - 剩下的报文段因此主机 A 发送到主机 B 的报文段中它的确认号就是 1000 。累积确认这里再举出一个例子比如主机 A 在发送 0 - 999 报文段后期望能够接受到 1000 之后的报文段但是主机 B 却给主机 A 发送了一个 1500 之后的报文段那么主机 A 是否还会继续进行等待呢答案显然是会的因为 TCP 只会确认流中至第一个丢失字节为止的字节因为 1500 虽然属于 1000 之后的字节但是主机 B 没有给主机 A 发送 1000 - 1499 之间的字节所以主机 A 会继续等待。在了解完序号和确认号之后我们下面来聊一下 TCP 的发送过程。下面是一个正常的发送过程TCP 通过肯定的确认应答(ACK) 来实现可靠的数据传输当主机 A将数据发出之后会等待主机 B 的响应。如果有确认应答(ACK)说明数据已经成功到达对端。反之则数据很可能会丢失。如下图所示如果在一定时间内主机 A 没有等到确认应答则认为主机 B 发送的报文段已经丢失并进行重发。主机 A 给主机 B 的响应可能由于网络抖动等原因无法到达那么在经过特定的时间间隔后主机 A 将重新发送报文段。主机 A 没有收到主机 B 的响应还可能是因为主机 B 在发送给主机 A 的过程中丢失。如上图所示由主机 B 返回的确认应答由于网络拥堵等原因在传送的过程中丢失并没有到达主机 A。主机 A 会等待一段时间如果在这段时间内主机 A 仍没有等到主机 B 的响应那么主机 A 会重新发送报文段。那么现在就存在一个问题如果主机 A 给主机 B 发送了一个报文段后主机 B 接受到报文段发送响应此刻由于网络原因这个报文段并未到达等到一段时间后主机 A 重新发送报文段然后此时主机 B 发送的响应在主机 A 第二次发送后失序到达主机 A那么主机 A 应该如何处理呢TCP RFC 并未为此做任何规定也就是说我们可以自己决定如何处理失序到达的报文段。一般处理方式有两种接收方立刻丢弃失序的报文段接收方接受失序到达的报文段并等待后续的报文段一般来说通常采取的做法是第二种。传输控制利用窗口控制提高速度前面我们介绍了 TCP 是以数据段的形式进行发送如果经过一段时间内主机 A 等不到主机 B 的响应主机 A 就会重新发送报文段接受到主机 B 的响应再会继续发送后面的报文段我们现在看到这一问一答的形式还存在许多条件比如响应未收到、等待响应等那么对崇尚性能的互联网来说这种形式的性能应该不会很高。那么如何提升性能呢为了解决这个问题TCP 引入了 窗口 这个概念即使在往返时间较长、频次很多的情况下它也能控制网络性能的下降听起来很牛批那它是如何实现的呢如下图所示我们之前每次请求发送都是以报文段的形式进行的引入窗口后每次请求都可以发送多个报文段也就是说一个窗口可以发送多个报文段。窗口大小就是指无需等待确认应答就可以继续发送报文段的最大值。在这个窗口机制中大量使用了 缓冲区 通过对多个段同时进行确认应答的功能。如下图所示发送报文段中高亮部分即是我们提到的窗口在窗口内即使没有收到确认应答也可以把请求发送出去。不过在整个窗口的确认应答没有到达之前如果部分报文段丢失那么主机 A 将仍会重传。为此主机 A 需要设置缓存来保留这些需要重传的报文段直到收到他们的确认应答。在滑动窗口以外的部分是尚未发送的报文段和已经接受到的报文段如果报文段已经收到确认则不可进行重发此时报文段就可以从缓冲区中清除。在收到确认的情况下会将窗口滑动到确认应答中确认号的位置如上图所示这样可以顺序的将多个段同时发送用以提高通信性能这种窗口也叫做 滑动窗口(Sliding window)。窗口控制和重发报文段的发送和接收必然伴随着报文段的丢失和重发窗口也是同样如此如果在窗口中报文段发送过程中出现丢失怎么办首先我们先考虑确认应答没有返回的情况。在这种情况下主机 A 发送的报文段到达主机 B是不需要再进行重发的。这和单个报文段的发送不一样如果发送单个报文段即使确认应答没有返回也要进行重发。窗口在一定程度上比较大时即使有少部分确认应答的丢失也不会重新发送报文段。我们知道如果在某个情况下由于发送的报文段丢失导致接受主机未收到请求或者主机返回的响应未到达客户端的话会经过一段时间重传报文。那么在使用窗口的情况下报文段丢失会怎么样呢如下图所示报文段 0 - 999 丢失后但是主机 A 并不会等待主机 A 会继续发送余下的报文段主机 B 发送的确认应答却一直是 1000同一个确认号的应答报文会被持续不断的返回如果发送端主机在连续 3 次收到同一个确认应答后就会将其所对应的数据重发这种机制要比之前提到的超时重发更加高效这种机制也被称为 高速重发控制。这种重发的确认应答也被称为 冗余 ACK(响应)。主机 B 在没有接收到自己期望序列号的报文段时会对之前收到的数据进行确认应答。发送端则一旦收到某个确认应答后又连续三次收到同样的确认应答那么就会认为报文段已经丢失。需要进行重发。使用这种机制可以提供更为快速的重发服务。流量控制前面聊的是传输控制下面 cxuan 再和你聊一下 流量控制。我们知道在每个 TCP 连接的一侧主机都会有一个 socket 缓冲区缓冲区会为每个连接设置接收缓存和发送缓存当 TCP 建立连接后从应用程序产生的数据就会到达接收方的接收缓冲区中接收方的应用程序并不一定会马上读取缓冲区的数据它需要等待操作系统分配时间片。如果此时发送方的应用程序产生数据过快而接收方读取接受缓冲区的数据相对较慢的话那么接收方中缓冲区的数据将会溢出。但是还好TCP 有 流量控制服务(flow-control service) 用于消除缓冲区溢出的情况。流量控制是一个速度匹配服务即发送方的发送速率与接受方应用程序的读取速率相匹配。TCP 通过使用一个 接收窗口(receive window) 的变量来提供流量控制。接受窗口会给发送方一个指示到底还有多少可用的缓存空间。发送端会根据接收端的实际接受能力来控制发送的数据量。接收端主机向发送端主机通知自己可以接收数据的大小发送端会发送不超过这个限度的数据这个大小限度就是窗口大小还记得 TCP 的首部么有一个接收窗口我们上面聊的时候说这个字段用于流量控制。它用于指示接收方能够/愿意接受的字节数量。那么只知道这个字段用于流量控制那么如何控制呢发送端主机会定期发送一个窗口探测包这个包用于探测接收端主机是否还能够接受数据当接收端的缓冲区一旦面临数据溢出的风险时窗口大小的值也随之被设置为一个更小的值通知发送端从而控制数据发送量。下面是一个流量控制示意图发送端主机根据接收端主机的窗口大小进行流量控制。由此也可以防止发送端主机一次发送过大数据导致接收端主机无法处理。如上图所示当主机 B 收到报文段 2000 - 2999 之后缓冲区已满不得不暂时停止接收数据。然后主机 A 发送窗口探测包窗口探测包非常小仅仅一个字节。然后主机 B 更新缓冲区接收窗口大小并发送窗口更新通知给主机 A然后主机 A 再继续发送报文段。在上面的发送过程中窗口更新通知可能会丢失一旦丢失发送端就不会发送数据所以窗口探测包会随机发送以避免这种情况发生。连接管理在继续介绍下面有意思的特性之前我们先来把关注点放在 TCP 的连接管理上因为没有 TCP 连接也就没有后续的一系列 TCP 特性什么事儿了。假设运行在一台主机上的进程想要和另一台主机上的进程建立一条 TCP 连接那么客户中的 TCP 会使用下面这些步骤与服务器中的 TCP 建立连接。首先客户端首先向服务器发送一个特殊的 TCP 报文段。这个报文段首部不包含应用层数据但是在报文段的首部中有一个 SYN 标志位 被置为 1。因此这个特殊的报文段也可以叫做 SYN 报文段。然后客户端随机选择一个初始序列号(client_isn) 并将此数字放入初始 TCP SYN 段的序列号字段中SYN 段又被封装在 IP 数据段中发送给服务器。一旦包含 IP 数据段到达服务器后服务端会从 IP 数据段中提取 TCP SYN 段将 TCP 缓冲区和变量分配给连接然后给客户端发送一个连接所允许的报文段。这个连接所允许的报文段也不包括任何应用层数据。然而它却包含了三个非常重要的信息。这些缓冲区和变量的分配使 TCP 容易受到称为 SYN 泛洪的拒绝服务攻击。首先SYN 比特被置为 1 。然后TCP 报文段的首部确认号被设置为 client_isn 1。最后服务器选择自己的初始序号(server_isn)并将其放置到 TCP 报文段首部的序号字段中。如果用大白话解释下就是我收到了你发起建立连接的 SYN 报文段这个报文段具有首部字段 client_isn。我同意建立该连接我自己的初始序号是 server_isn。这个允许连接的报文段被称为 SYNACK 报文段第三步在收到 SYNACK 报文段后客户端也要为该连接分配缓冲区和变量。客户端主机向服务器发送另外一个报文段最后一个报文段对服务器发送的响应报文做了确认确认的标准是客户端发送的数据段中确认号为 server_isn 1因为连接已经建立所以 SYN 比特被置为 0 。以上就是 TCP 建立连接的三次数据段发送过程也被称为 三次握手。一旦完成这三个步骤客户和服务器主机就可以相互发送报文段了在以后的每一个报文段中SYN 比特都被置为 0 整个过程描述如下图所示在客户端主机和服务端主机建立连接后参与一条 TCP 连接的两个进程中的任何一个都能终止 TCP 连接。连接结束后主机中的缓存和变量将会被释放。假设客户端主机想要终止 TCP 连接它会经历如下过程客户应用进程发出一个关闭命令客户 TCP 向服务器进程发送一个特殊的 TCP 报文段这个特殊的报文段的首部标志 FIN 被设置为 1 。当服务器收到这个报文段后就会向发送方发送一个确认报文段。然后服务器发送它自己的终止报文段FIN 位被设置为 1 。客户端对这个终止报文段进行确认。此时在两台主机上用于该连接的所有资源都被释放了如下图所示在一个 TCP 连接的生命周期内运行在每台主机中的 TCP 协议都会在各种 TCP 状态(TCP State) 之间进行变化TCP 的状态主要有 LISTEN、SYN-SEND、SYN-RECEIVED、ESTABLISHED、FIN-WAIT-1、FIN-WAIT-2、CLOSE-WAIT、CLOSING、LAST-ACK、TIME-WAIT 和 CLOSED 。这些状态的解释如下LISTEN: 表示等待任何来自远程 TCP 和端口的连接请求。SYN-SEND: 表示发送连接请求后等待匹配的连接请求。SYN-RECEIVED: 表示已接收并发送连接请求后等待连接确认也就是 TCP 三次握手中第二步后服务端的状态ESTABLISHED: 表示已经连接已经建立可以将应用数据发送给其他主机上面这四种状态是 TCP 三次握手所涉及的。FIN-WAIT-1: 表示等待来自远程 TCP 的连接终止请求或者等待先前发送的连接终止请求的确认。FIN-WAIT-2: 表示等待来自远程 TCP 的连接终止请求。CLOSE-WAIT: 表示等待本地用户的连接终止请求。CLOSING: 表示等待来自远程 TCP 的连接终止请求确认。LAST-ACK: 表示等待先前发送给远程 TCP 的连接终止请求的确认包括对它的连接终止请求的确认。TIME-WAIT: 表示等待足够的时间以确保远程 TCP 收到其连接终止请求的确认。CLOSED: 表示连接已经关闭无连接状态。上面 7 种状态是 TCP 四次挥手也就是断开链接所设计的。TCP 的连接状态会进行各种切换这些 TCP 连接的切换是根据事件进行的这些事件由用户调用OPEN、SEND、RECEIVE、CLOSE、ABORT 和 STATUS。涉及到 TCP 报文段的标志有 SYN、ACK、RST 和 FIN 当然还有超时。我们下面加上 TCP 连接状态后再来看一下三次握手和四次挥手的过程。三次握手建立连接下图画出了 TCP 连接建立的过程。假设图中左端是客户端主机右端是服务端主机一开始两端都处于CLOSED关闭状态。服务端进程准备好接收来自外部的 TCP 连接一般情况下是调用 bind、listen、socket 三个函数完成。这种打开方式被认为是 被动打开(passive open)。然后服务端进程处于 LISTEN 状态等待客户端连接请求。客户端通过 connect 发起主动打开(active open)向服务器发出连接请求请求中首部同步位 SYN 1同时选择一个初始序号 sequence 简写 seq x。SYN 报文段不允许携带数据只消耗一个序号。此时客户端进入 SYN-SEND 状态。服务器收到客户端连接后需要确认客户端的报文段。在确认报文段中把 SYN 和 ACK 位都置为 1 。确认号是 ack x 1同时也为自己选择一个初始序号 seq y。请注意这个报文段也不能携带数据但同样要消耗掉一个序号。此时TCP 服务器进入 SYN-RECEIVED(同步收到) 状态。客户端在收到服务器发出的响应后还需要给出确认连接。确认连接中的 ACK 置为 1 序号为 seq x 1确认号为 ack y 1。TCP 规定这个报文段可以携带数据也可以不携带数据如果不携带数据那么下一个数据报文段的序号仍是 seq x 1。这时客户端进入 ESTABLISHED (已连接) 状态服务器收到客户的确认后也进入 ESTABLISHED 状态。TCP 建立一个连接需要三个报文段释放一个连接却需要四个报文段。四次挥手数据传输结束后通信的双方可以释放连接。数据传输结束后的客户端主机和服务端主机都处于 ESTABLISHED 状态然后进入释放连接的过程。TCP 断开连接需要历经的过程如下客户端应用程序发出释放连接的报文段并停止发送数据主动关闭 TCP 连接。客户端主机发送释放连接的报文段报文段中首部 FIN 位置为 1 不包含数据序列号位 seq u此时客户端主机进入 FIN-WAIT-1(终止等待 1) 阶段。服务器主机接受到客户端发出的报文段后即发出确认应答报文确认应答报文中 ACK 1生成自己的序号位 seq vack u 1然后服务器主机就进入 CLOSE-WAIT(关闭等待) 状态这个时候客户端主机 - 服务器主机这条方向的连接就释放了客户端主机没有数据需要发送此时服务器主机是一种半连接的状态但是服务器主机仍然可以发送数据。客户端主机收到服务端主机的确认应答后即进入 FIN-WAIT-2(终止等待2) 的状态。等待客户端发出连接释放的报文段。当服务器主机没有数据发送后应用进程就会通知 TCP 释放连接。这时服务端主机会发出断开连接的报文段报文段中 ACK 1序列号 seq w因为在这之间可能已经发送了一些数据所以 seq 不一定等于 v 1。ack u 1在发送完断开请求的报文后服务端主机就进入了 LAST-ACK(最后确认)的阶段。客户端收到服务端的断开连接请求后客户端需要作出响应客户端发出断开连接的报文段在报文段中ACK 1, 序列号 seq u 1因为客户端从连接开始断开后就没有再发送数据ack w 1然后进入到 TIME-WAIT(时间等待) 状态请注意这个时候 TCP 连接还没有释放。必须经过时间等待的设置也就是 2MSL 后客户端才会进入 CLOSED 状态时间 MSL 叫做最长报文段寿命Maximum Segment Lifetime。服务端主要收到了客户端的断开连接确认后就会进入 CLOSED 状态。因为服务端结束 TCP 连接时间要比客户端早而整个连接断开过程需要发送四个报文段因此释放连接的过程也被称为四次挥手。什么是 TIME-WAIT我上面只是简单提到了一下 TIME-WAIT 状态和 2MSL 是啥下面来聊一下这两个概念。MSL 是 TCP 报文段可以存活或者驻留在网络中的最长时间。RFC 793 定义了 MSL 的时间是两分钟但是具体的实现还要根据程序员来指定一些实现采用了 30 秒的这个最大存活时间。那么为什么要等待 2MSL 呢主要是因为两个理由为了保证最后一个响应能够到达服务器因为在计算机网络中最后一个 ACK 报文段可能会丢失从而致使客户端一直处于 LAST-ACK 状态等待客户端响应。这时候服务器会重传一次 FINACK 断开连接报文客户端接收后再重新确认重启定时器。如果客户端不是 2MSL 在客户端发送 ACK 后直接关闭的话如果报文丢失那么双方主机会无法进入 CLOSED 状态。还可以防止已失效的报文段。客户端在发送最后一个 ACK 之后再经过经过 2MSL就可以使本链接持续时间内所产生的所有报文段都从网络中消失。从而保证在关闭连接后不会有还在网络中滞留的报文段去骚扰服务器。这里注意一点在服务器发送了 FIN-ACK 之后会立即启动超时重传计时器。客户端在发送最后一个 ACK 之后会立即启动时间等待计时器。说好的 RST 呢说好的 RST、SYN、FIN 标志用于连接的建立和关闭那么 SYN 和 FIN 都现身了那 RST 呢也是啊我们上面探讨的都是一种理想的情况就是客户端服务器双方都会接受传输报文段的情况还有一种情况是当主机收到 TCP 报文段后其 IP 和端口号不匹配的情况。假设客户端主机发送一个请求而服务器主机经过 IP 和端口号的判断后发现不是给这个服务器的那么服务器就会发出一个 RST 特殊报文段给客户端。因此当服务端发送一个 RST 特殊报文段给客户端的时候它就会告诉客户端没有匹配的套接字连接请不要再继续发送了。上面探讨的是 TCP 的情况那么 UDP 呢使用 UDP 作为传输协议后如果套接字不匹配的话UDP 主机就会发送一个特殊的 ICMP 数据报。SYN 洪泛攻击下面我们来讨论一下什么是 SYN 洪泛攻击。我们在 TCP 的三次握手中已经看到服务器为了响应一个收到的 SYN分配并初始化变量连接和缓存然后服务器发送一个 SYNACK 作为响应然后等待来自于客户端的 ACK 报文。如果客户端不发送 ACK 来完成最后一步的话那么这个连接就处在一个挂起的状态也就是半连接状态。攻击者通常在这种情况下发送大量的 TCP SYN 报文段服务端继续响应但是每个连接都完不成三次握手的步骤。随着 SYN 的不断增加服务器会不断的为这些半开连接分配资源导致服务器的连接最终被消耗殆尽。这种攻击也是属于 Dos 攻击的一种。抵御这种攻击的方式是使用 SYN cookie 下面是它的工作流程介绍当服务器收到一个 SYN 报文段时它并不知道这个报文段是来自哪里是来自攻击者主机还是客户端主机(虽然攻击者也是客户端不过这么说更便于区分) 。因此服务器不会为报文段生成一个半开连接。与此相反服务器生成一个初始的 TCP 序列号这个序列号是 SYN 报文段的源和目的 IP 地址与端口号这个四元组构造的一个复杂的散列函数这个散列函数生成的 TCP 序列号就是 SYN Cookie用于缓存 SYN 请求。然后服务器会发送带着 SYN Cookie 的 SYNACK 分组。有一点需要注意的是服务器不会记忆这个 Cookie 或 SYN 的其他状态信息。如果客户端不是攻击者的话它就会返回一个 ACK 报文段。当服务器收到这个 ACK 后需要验证这个 ACK 与 SYN 发送的是否相同验证的标准就是确认字段中的确认号和序列号源和目的 IP 地址与端口号以及和散列函数的是否一致散列函数的结果 1 是否和 SYNACK 中的确认值相同。(大致是这样说的不对还请读者纠正) 。如果有兴趣读者可以自行深入了解。如果是合法的服务器就会生成一个具有套接字的全开连接。如果客户端没有返回 ACK即认为是攻击者那么这样也没关系服务器没有收到 ACK不会分配变量和缓存资源不会对服务器产生危害。拥塞控制有了 TCP 的窗口控制后使计算机网络中两个主机之间不再是以单个数据段的形式发送了而是能够连续发送大量的数据包。然而大量数据包同时也伴随着其他问题比如网络负载、网络拥堵等问题。TCP 为了防止这类问题的出现使用了 拥塞控制 机制拥塞控制机制会在面临网络拥塞时遏制发送方的数据发送。拥塞控制主要有两种方法端到端的拥塞控制: 因为网络层没有为运输层拥塞控制提供显示支持。所以即使网络中存在拥塞情况端系统也要通过对网络行为的观察来推断。TCP 就是使用了端到端的拥塞控制方式。IP 层不会向端系统提供有关网络拥塞的反馈信息。那么 TCP 如何推断网络拥塞呢如果超时或者三次冗余确认就被认为是网络拥塞TCP 会减小窗口的大小或者增加往返时延来避免。网络辅助的拥塞控制: 在网络辅助的拥塞控制中路由器会向发送方提供关于网络中拥塞状态的反馈。这种反馈信息就是一个比特信息它指示链路中的拥塞情况。下图描述了这两种拥塞控制方式TCP 拥塞控制如果你看到这里那我就暂定认为你了解了 TCP 实现可靠性的基础了那就是使用序号和确认号。除此之外另外一个实现 TCP 可靠性基础的就是 TCP 的拥塞控制。如果说TCP 所采用的方法是让每一个发送方根据所感知到的网络的拥塞程度来限制发出报文段的速率如果 TCP 发送方感知到没有什么拥塞则 TCP 发送方会增加发送速率如果发送方感知沿着路径有阻塞那么发送方就会降低发送速率。但是这种方法有三个问题TCP 发送方如何限制它向其他连接发送报文段的速率呢一个 TCP 发送方是如何感知到网络拥塞的呢当发送方感知到端到端的拥塞时采用何种算法来改变其发送速率呢我们先来探讨一下第一个问题TCP 发送方如何限制它向其他连接发送报文段的速率呢我们知道 TCP 是由接收缓存、发送缓存和变量(LastByteRead, rwnd等)组成。发送方的 TCP 拥塞控制机制会跟踪一个变量即 拥塞窗口(congestion window) 的变量拥塞窗口表示为 cwnd用于限制 TCP 在接收到 ACK 之前可以发送到网络的数据量。而接收窗口(rwnd) 是一个用于告诉接收方能够接受的数据量。一般来说发送方未确认的数据量不得超过 cwnd 和 rwnd 的最小值也就是LastByteSent - LastByteAcked min(cwnd,rwnd)由于每个数据包的往返时间是 RTT我们假设接收端有足够的缓存空间用于接收数据我们就不用考虑 rwnd 了只专注于 cwnd那么该发送方的发送速率大概是 cwnd/RTT 字节/秒 。通过调节 cwnd发送方因此能调整它向连接发送数据的速率。一个 TCP 发送方是如何感知到网络拥塞的呢这个我们上面讨论过是 TCP 根据超时或者 3 个冗余 ACK 来感知的。当发送方感知到端到端的拥塞时采用何种算法来改变其发送速率呢 ?这个问题比较复杂且容我娓娓道来一般来说TCP 会遵循下面这几种指导性原则如果在报文段发送过程中丢失那就意味着网络拥堵此时需要适当降低 TCP 发送方的速率。一个确认报文段指示发送方正在向接收方传递报文段因此当对先前未确认报文段的确认到达时能够增加发送方的速率。为啥呢因为未确认的报文段到达接收方也就表示着网络不拥堵能够顺利到达因此发送方拥塞窗口长度会变大所以发送速率会变快带宽探测带宽探测说的是 TCP 可以通过调节传输速率来增加/减小 ACK 到达的次数如果出现丢包事件就会减小传输速率。因此为了探测拥塞开始出现的频率 TCP 发送方应该增加它的传输速率。然后慢慢使传输速率降低进而再次开始探测看看拥塞开始速率是否发生了变化。在了解完 TCP 拥塞控制后下面我们就该聊一下 TCP 的 拥塞控制算法(TCP congestion control algorithm) 了。TCP 拥塞控制算法主要包含三个部分慢启动、拥塞避免、快速恢复下面我们依次来看一下慢启动当一条 TCP 开始建立连接时cwnd 的值就会初始化为一个 MSS 的较小值。这就使得初始发送速率大概是 MSS/RTT 字节/秒 比如要传输 1000 字节的数据RTT 为 200 ms 那么得到的初始发送速率大概是 40 kb/s 。实际情况下可用带宽要比这个 MSS/RTT 大得多因此 TCP 想要找到最佳的发送速率可以通过 慢启动(slow-start) 的方式在慢启动的方式中cwnd 的值会初始化为 1 个 MSS并且每次传输报文确认后就会增加一个 MSScwnd 的值会变为 2 个 MSS这两个报文段都传输成功后每个报文段 1会变为 4 个 MSS依此类推每成功一次 cwnd 的值就会翻倍。如下图所示发送速率不可能会一直增长增长总有结束的时候那么何时结束呢慢启动通常会使用下面这几种方式结束发送速率的增长。如果在慢启动的发送过程出现丢包的情况那么 TCP 会将发送方的 cwnd 设置为 1 并重新开始慢启动的过程此时会引入一个 ssthresh(慢启动阈值) 的概念它的初始值就是产生丢包的 cwnd 的值 / 2即当检测到拥塞时ssthresh 的值就是窗口值的一半。第二种方式是直接和 ssthresh 的值相关联因为当检测到拥塞时ssthresh 的值就是窗口值的一半那么当 cwnd ssthresh 时每次翻番都可能会出现丢包所以最好的方式就是 cwnd 的值 ssthresh 这样 TCP 就会转为拥塞控制模式结束慢启动。慢启动结束的最后一种方式就是如果检测到 3 个冗余 ACKTCP 就会执行一种快速重传并进入恢复状态。拥塞避免当 TCP 进入拥塞控制状态后cwnd 的值就等于拥塞时值的一半也就是 ssthresh 的值。所以无法每次报文段到达后都将 cwnd 的值再翻倍。而是采用了一种相对保守的方式每次传输完成后只将 cwnd 的值增加一个 MSS比如收到了 10 个报文段的确认但是 cwnd 的值只增加一个 MSS。这是一种线性增长模式它也会有增长逾值它的增长逾值和慢启动一样如果出现丢包那么 cwnd 的值就是一个 MSSssthresh 的值就等于 cwnd 的一半或者是收到 3 个冗余的 ACK 响应也能停止 MSS 增长。如果 TCP 将 cwnd 的值减半后仍然会收到 3 个冗余 ACK那么就会将 ssthresh 的值记录为 cwnd 值的一半进入 快速恢复 状态。快速恢复在快速恢复中对于使 TCP 进入快速恢复状态缺失的报文段对于每个收到的冗余 ACKcwnd 的值都会增加一个 MSS 。当对丢失报文段的一个 ACK 到达时TCP 在降低 cwnd 后进入拥塞避免状态。如果在拥塞控制状态后出现超时那么就会迁移到慢启动状态cwnd 的值被设置为 1 个 MSSssthresh 的值设置为 cwnd 的一半。 往期推荐 千万不要这样写代码9种常见的OOM场景演示Java中竟有18种队列45张图安排45 张图深度解析 Netty 架构与原理关注我每天陪你进步一点点
http://www.yutouwan.com/news/474124/

相关文章:

  • 在国外做盗版网站seo推广目的
  • 规范网站维护 建设 管理wordpress新增站点
  • 怎样自己做网页设计网站手机移动网站建设
  • 英雄联盟网站建设地产网站开发公司
  • 广西南宁官方网站企业企业做企业网站的好处
  • 建网站服务器是什么东西做网站80端口
  • 怎么知道网站用wordpress有专业制作网站的公司吗
  • 找做网站平台公司发债
  • 佛山网站设计讯息互动平台游戏
  • 茂名建设公司网站丹阳是哪里
  • 网站怎么做值班表女生学软件工程很难吗
  • 网站建设氺首选金手指14什么网站教你做美食
  • 交易网站建设需要学什么软件网站建设拟采用的技术路线
  • 网新企业网站管理系统WordPress仿制
  • 网页设计与网站建设分析解析域名就可以做网站
  • 大连网站建设运营百度一下官网搜索引擎
  • 网站的ftp账号和密码是什么一家企业如何建设自己的网站 下载
  • 凤台做网站大连网页设计公司排名
  • 一站式服务平台官网绍兴网站快速排名优化
  • 我想创业做网站服务五象新区开发建设指挥部网站
  • 做网站公司怎么找网站建设前就应该进行网站推广工作
  • 关闭站长工具seo综合查询百度快照搜索引擎
  • 长春站建筑网站服务器和空间大小
  • 服装设计网站有哪些网站代理在线
  • 怎么做网站能快速赚钱温州网站建设wmwl
  • 做网站需要团队还是一个人专业做财经直播网站
  • 珠海网站建易搜互联免费音乐网站建设
  • 保定做网站的公司推广方式图片
  • 东营网站建设优选案例注册个人订阅号
  • 网站建设办公软件销售技巧后期网站建设及维护推广