手机网站 域名解析,广告投放平台主要有哪些,企业集团网站网站建设方案,黄骅港招聘四、滑动窗口机制
五、流量控制
六、拥塞控制 (安全机制)
七、延迟应答 (效率机制)
八、捎带应答 (效率机制)
九、粘包问题
十、保活机制
TCP总结 四、滑动窗口机制 滑动窗口机制#xff0c;是在可靠性的前提下#xff0c;进一步地提高传输效率 认识滑动窗口
一发一收…四、滑动窗口机制
五、流量控制
六、拥塞控制 (安全机制)
七、延迟应答 (效率机制)
八、捎带应答 (效率机制)
九、粘包问题
十、保活机制
TCP总结 四、滑动窗口机制 滑动窗口机制是在可靠性的前提下进一步地提高传输效率 认识滑动窗口
一发一收的方式TCP 协议需要对数据进行确认后才可以发送下一个数据包如图 如上图发送端每发送一个数据包都需要得到接收端的确认应答以后才可以发送下一个数据包是一问一答的串行过程即每次传输数据都需要等待一个对应的等待时间那么传输 N 份数据就需要等待 N 次应答时间总的传输时间N 份数据传输时间 N 份应答传输时间 一发一收的方式性能较低那么我们一次发送多条数据就可以大大地提高性能(其实是将多个段的等待时间重叠在一起了)如图 滑动窗口本质上是批量传输数据
总的传输时间N 份数据传输时间重叠成了一份时间N 份应答传输时间重叠成了一份时间相当于把多份数据的传输时间和等待 ACK 的时间压缩成一份了总的等待时间少了传输效率也就高了 a. 窗口
窗口大小: 不等待 ACK 的情况下批量发送的最大数据量就叫窗口大小 (如上图就是4000个字节4个字段) 发送前四个字段的时候不需要等待任何 ACK直接发送 收到第一个ACK后滑动窗口向后移动继续发送第五个字段的数据依次类推 操作系统内核为了维护这个滑动窗口需要开辟 发送缓冲区 来记录当前还有哪些数据没有应答只有确认应答过的数据才能从缓冲区删掉 窗口越大 则网络的吞吐率就越高 b. 滑动
窗口范围内的数据是在等待这些数据的 ACK (已经被发送出去) 如上图当发送方收到 2001 的 ACK意味着 1001 - 2000 的数据对方已经接收此时立刻继续传输 5001 - 6000 的数据则等待 ACK 的数据包的序号就是 2001300140015001 丢包问题处理
丢包的两种情况如图 情况1: 确认应答 (ACK) 丢包
不需要进行额外的处理在这种情况下部分 ACK 丢了并不要紧因为可以通过后续的 ACK进 行确认 理解确认序号的含义
从当前序号开始前面的数据都已经正确到了
如上图是 1001 的 ACK 丢失2001 的 ACK 没丢此时发送方收到 2001 之后就会认为 1 - 1000 这个数据也是顺利到达的1001 丢了无所谓2001 的 ACK 能够包含 1001 ACK 中的信息 情况2: 数据包丢失
如下图若是 1001-2000 丢失然后 2001-30003001-4000 等后边的几个数据都顺利到达此时主机 B 反馈的 ACK 的确认序号始终是 1001
此时若主机 A 发现连续几个 ACK 都是1001主机 A 就知道1001 这个数据丢失就会重传 1001
在重传 1001 之前收到的确认序号都是 1001
当主机 B 收到 1001 这个数据的时候由于 2001-7000 这些数据前边已经收到过接下来的 ACK 就从 7001 开始
此处的重传只是重传丢了的数据其他数据不需要额外重传—— 快速重传(搭配滑动窗口下的超时重传) 乱序传输: 五、流量控制 流量控制: 根据接收方的处理能力来反向制衡发送方的发送效率(窗口大小) (通过接收缓冲区的 “剩余空间大小” 来决定发送方的速率) 窗口大小不能无限大传输速率太快接收方可能处理不过来
在使用滑动窗口机制进行数据传输时发送方根据实际情况发送数据包接收端接收数据包由于接收端处理数据包的能力是不同的因此可能出现两种情况 若窗口过小发送端发送少量的数据包接收端很快就处理了并且还能处理更多的数据包当传输比较大的数据时需要不停地等待发送方就会造成很大的延迟 若窗口过大发送端发送大量的数据包而接收端处理不了这么多的数据包就会堵塞链路若丢弃这些本应该接收的数据包又会触发重发机制 (第一次的窗口大小是根据链路带宽的大小来决定的) 发送数据包接收端接收这些数据包并返回确认应答包告诉发送端自己下次希望收到的数据包是多少新的窗口大小发送端收到确认应答包以后将以该窗口大小进行发送数据包 接收端将自己可以接收的缓冲区大小放入 TCP 首部中的 “窗口大小” 字段通过 ACK 端通知发送端 窗口大小字段越大说明网络的吞吐量越高 接收端一旦发现自己的缓冲区快满了就会将窗口大小设置成一个更小的值通知给发送端 发送端接受到这个窗口之后就会减慢自己的发送速度 如果接收端缓冲区满了就会将窗口置为0这时发送方不再发送数据但是需要定期发送一个窗口探测数据段使接收端把窗口大小告诉发送端 如下图: 图解: 假设初始窗口大小为4000发送端发送 4 个数据包分别为 1-10001001-20002001-3000 和 3001-4000 接收端接收数据包接收到 1-1000 数据包之后设置窗口大小为 3000告诉发送端自己现在只能处理 3 个数据包下一次请发送 3 个数据包 发送端接收到确认应答包查看到接收端返回窗口大小为 3000知道接收端处理了 1 个数据包接着继续发送: 1001-20002001-3000 和 3001-4000 接收方收到之后缓冲区只能处理 2 个数据包发过去的第 3 个数据包 3001-4000 没有被处理这说明此时接收端只能处理 2 个数据包第 3 个数据包还需要重新发送 当窗口为 0 时发送方会暂停发送也会定时发送一个探测报文因为接收缓冲区的数据随时可能被取走一旦取走就可以接收新的数据滑动窗口大小是动态变化的 六、拥塞控制 (安全机制) 拥塞控制是考虑网络传输路径上的拥堵程度 虽然TCP有了滑动窗口这个大杀器能够高效可靠的发送大量的数据但是如果在刚开始阶段就发送大量的数据仍然可能引发问题因为网络上有很多的计算机可能当前的网络状态就已经比较拥堵在不清楚当前网络状态下贸然发送大量的数据是很有可能雪上加霜因此TCP引入 慢启动 机制先发少量的数据探探路摸清当前的网络拥堵状态再决定按照多大的速度传输数据 线增积减 (和式增加积式减少) 像上面这样的拥塞窗口增长速度是指数级别的“慢启动” 只是指初使时慢但是增长速度非常快具体的增长如下图: 刚开始的时候从1指数增长到达阈值后开始线性增长如果出现网络阻塞直接减小到初始值然后再次指数增长到达新的阈值(新阈值为上次阻塞窗口大小的一半)再次线性增长直到网络阻塞一直这样动态变换循环 为啥要动态变化
网络的拥堵情况是瞬息万变的我们要随时根据网络的实际情况进行动态调整 (随时适应网络的变化过程) 七、延迟应答 (效率机制) 目的是为了提高效率在流量控制的基础上尽量返回一个合理但又比较大的窗口 在前面我们提到在发送端发送数据后接收数据的主机需要返回 ACK应答此时若立刻返回窗口可能比较小 (因为缓冲区的数据只处理了一部分)所以 TCP 采用了延迟应答机制举例 不带延迟应答:
有一个超市假设泡面库存最多存放100箱当前已经存了80箱空余20箱
第二天一早送货小哥来问“老板你明天需要多少面”
老板“你最多送20箱就行。” 带延迟应答:
第二天一早送货小哥来问“老板你明天需要多少面”
老板“我晚上的时候打电话告诉你需要多少。”
(可能白天又卖出了10箱第二天最多送10箱即可) 延时应答其实就是让 ACK 的发送时间晚一会儿 (不影响可靠性的前提下)
延迟的时间中就会给应用程序提供更多的消费数据的机会此时时间到了再发送 ACK 的时候得到的窗口大小(接收缓冲区的剩余空间就会更大一些) 窗口越大网络吞吐量就越大传输效率就越高我们的目标是在保证网络不拥塞的情况下尽量提高传输效率 问所有的包都可以延迟应答么?
肯定不是 数量限制: 每隔 N 个包就应答一次 (N一般为2) 时间限制: 超过最大延迟时间就应答一次 (时间一般取200 ms延迟应答的等待时间不能超过超时重传的时间不然就重传了) 八、捎带应答 (效率机制) 在延迟应答的基础上为了进一步提高程序运行效率而引入的机制 在很多情况下客户端和服务器的通信模式一般都是 Request - Response 模式即 “一问一答”
如图: 注意:
三次握手中间的 SYN 和 ACK 都是由内核决定的不涉及不同的时机
上述提到的四次挥手的过程ACK 是内核决定的发的 FIN (close方法) 是应用程序代码决定的 九、粘包问题 严格说粘包问题不是 TCP 自身的机制而是面向字节流传输所具备的共性问题
粘包指粘的是应用层数据包导致数据在处理的时候容易读取半个应用层数据包 面向字节流: 指的是一次读一个字节或者一次读两个字节或者一次读 N 个字节都行 举例双方建立连接需要在连接后一段时间内发送不同结构数据如连接后有好几种结构 “你好不好” “好个P”
读多少个字节才是一个完整的应用层数据包这个是不清楚的
若一次读一个汉字读出来就是 “好”若一次读三个汉字读出来就是 “好个P”
读法不一样最终的含义差异也很大读取应用层数据就不应该只读半个包 如何避免粘包问题
归根结底就是一句话明确两个包之间的边界
TCP 协议本身不帮你区分应用层数据包相对而言UDP 协议没这个问题 (UDP 协议就是按照数据包为单位进行收发的) 方式1 - 使用分隔符
比如上述回答改为 “好个P” 用分号 当做两个包的分隔符读数据一直读到分号才认为是一个完整的应用层数据包
应用层协议是程序猿自己来定的只要保证分隔符不和正文冲突即可** 方式2 - 明确包的长度
比如上述用例改为 “4你好不好3好个P” 先读取最开始的四个字节得到包的长度3继续读取3个汉字于是就读取一个完整的包 HTTP 协议基于 TCP 的应用层协议自己就会处理好粘包问题上述两种方式都使用到了: 对于 GET 请求分隔符就是空行
对于 POST 请求Content-length 来指定包的长度 思考对于UDP协议来说是否也存在 “粘包问题” 呢 对于UDP如果还没有上层交付数据UDP的报文长度仍然在。同时UDP是一个一个把数据交付给应用层就有很明确的数据边界 站在应用层的站在应用层的角度使用UDP的时候要么收到完整的UDP报文要么不收不会出现半个的情况
十、保活机制 双方建立交互的连接并不是一直存在数据交互有些连接会在数据交互完毕后主动释放连接而有些不会那么在长时间无数据交互的时间段内交互双方都有可能出现掉电、死机、异常重启还是中间路由网络无故断开、NAT超时等各种意外 在这些 “异常情况” 下TCP 对于连接会有一些特殊的处理 举例
1.进程崩溃: 这种情况TCP 连接会正常四次挥手 (只要是进程退出都会自动关闭相关的文件)
2.主机关机(按照流程关机)关机的时候会强制先杀进程杀进程过程之中就要进行四次挥手了
3.主机断电 / 网线断开: a) 接收方断电。 对端尝试发送消息的时候就会出现没有 ACK 的情况 — 于是就会触发超时重传 — 重传一定次数就会重置连接 — 放弃连接 b) 发送方断电。对端尝试接收消息对于接收端来说本来也不知道发送方什么时候发送难道就一直等吗 解决方案 — 心跳包 TCP 的通信双方即使在没有数据交互的过程中也会定时相互传输一个没有数据业务意义的 “心跳包”只是为了证明 “我活着”一旦隔了一段时间都没有收到对方的心跳包就可以认为对端挂了
TCP总结 TCP 之所以复杂是因为它既要保证可靠性同时又尽可能地提高性能 可靠性
校验和序列号
确认应答超时重传
连接管理流量控制拥塞控制 提高性能
滑动窗口快速重传
延迟应答捎带应答 其他
定时器超时重传定时器保活定时器TIME_WAIT定时器等