TCP 糊涂窗口综合症(silly window syndrome)与 rate-based 流控
昨天同事给我看了一个有趣的 case,接收端抓包:
现象就是这样,但结论也很明显:
- ack 渐长,win 渐缩,有数据陆续到达 rcvbuff,但 app 尚未读取。
- ack 不变,win 渐长,没有新数据到达,app 持续读取数据。
据说这是个 iOS 系统的 case。
该现象与 Linux TCP 并不匹配,Linux TCP 仅在下面的情况才会发送 win update:
- 窗口从 0 变为非 0,且…
- rwnd 腾出了一半的空间。
条件过于苛刻。做以下实验:
Linux server 端代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>#define SIZE 16384
#define PORT 1234void senddata(int csd)
{char buff[SIZE];int n, i;for (i = 0; i < 8; i++) {write(csd, buff, sizeof(buff));}getchar();
}int main()
{int sockfd, csd, len;struct sockaddr_in servaddr, cli;sockfd = socket(AF_INET, SOCK_STREAM, 0);servaddr.sin_family = AF_INET;servaddr.sin_addr.s_addr = htonl(INADDR_ANY);servaddr.sin_port = htons(PORT);bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));listen(sockfd, 5);len = sizeof(cli);while(1) {csd = accept(sockfd, (struct sockaddr *)&cli, &len);senddata(csd);close(csd);}
}
Linux client 和 MacOS client 端代码:
#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>#define SIZE 2048
#define PORT 1234void recvdata(int sd)
{char buff[SIZE];int n, i;getchar();for (i = 0; i < 64; i++) {read(sd, buff, sizeof(buff));}
}int main()
{int sd, connfd;struct sockaddr_in servaddr, cli;sd = socket(AF_INET, SOCK_STREAM, 0);servaddr.sin_family = AF_INET;servaddr.sin_addr.s_addr = inet_addr("192.168.10.6");servaddr.sin_port = htons(PORT);connect(sd, (struct sockaddr*)&servaddr, sizeof(servaddr));recvdata(sd);close(sd);
}
运行 client 后敲回车,结果显示,MacOS client 在敲下会车后从 rcvbuff 读取了一定字节后就会发送 win update,而 Linux 不会。
OK,开始评谈。
早期,资源所限,为避免糊涂窗口综合症,TCP 采取一定措施规避,但在事情的反面反而阻碍了 rate-based 流控。
糊涂窗口综合症本质上包括下面因素:
- 接收端接收数据太慢。
- 发送端产生数据太慢。
- 担心网络上充斥小包。
但根据管道模型,理论上哪怕一次通告 1 字节 rwnd,只要通告速度足够快,依然可达任意带宽。问题是:
- 如果接收端接收速度足够快,窗口还糊涂吗?
- 既然接收端慢可以影响发送,为什么接收端快就不能呢?
如何从面向 rcvbuff 的流控转向面向应用程序接收能力的 rate-based 流控,问题就在于何时发送 win update。Linux TCP 在应用程序读取数据后发送 win update 的条件太苛刻。
如今早年的限制已不再:
- 内存足够大,可承受更大的意外突发。
- 带宽足够大,可容忍长报头损失的载荷率。
- 拥塞控制纷纷从 buffer-based 转向 rate-based。
Linux TCP 在 30 年后依然是很吝啬的实现,旨在节省资源以适应早期环境,MacOS 似乎好一点,但我还没 deep into Darwin 代码,不评说。
糊涂窗口综合症是慢速环境下的症状,减缓症状的措施在高速环境下必然掣肘。
看看 win update after read 的益处:
皮鞋不会胖
蜷缩着过活,总希望是大梦一场,
可我挺直了身子,却还是看不到光,
你说我不够努力,我说我没有梦想,
街头徘徊着梦,需要与酒邂逅。
浙江温州皮鞋湿,下雨进水不会胖。
TCP 糊涂窗口综合症(silly window syndrome)与 rate-based 流控相关推荐
- 糊涂窗口综合症和Nagle算法
本篇文章转载自:http://www.cnblogs.com/zhaoyl/archive/2012/09/20/2695799.html,用于记录自己对于TCP网络中糊涂窗口综合症和Nagle算法的 ...
- TCP滑动窗口(Sliding Window)原理
---------------- 版权声明:本文为CSDN博主「CQ小子」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明. 原文链接:https://blog.csd ...
- 传输层协议TCP—滑动窗口(6)
1 传输控制 TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的.可靠的.基于字节流的传输层通信协议.在前面的章节中,我们介绍了 TCP 连接的相关概念 ...
- TCP滑动窗口,流量控制,拥塞控制详解
引言 我们知道TCP是每发送一个数据,都要进行一次确认应答报文的.当上一个收到应答时,才会继续发送下一个.这种方式很显然效率比较低 滑动窗口 窗口大小就是无需等待应答,而可以继续发送数据的最大值 滑动 ...
- tcp下载窗口太小的问题_图解 TCP 重传、滑动窗口、流量控制、拥塞控制
相信大家都知道 TCP 是一个可靠传输的协议,那如何它是如何保证可靠的呢? 为了实现可靠性传输,需要考虑很多事情,例如数据的破坏.丢包.重复以及分片顺序混乱等问题.如不能解决这些问题,也就无从谈起可靠 ...
- tcp欢动窗口机制_TCP协议中的窗口机制------滑动窗口详解
一.窗口机制的分类 在TCP协议当中窗口机制分为两种: 1.固定的窗口大小 2.滑动窗口 二.固定窗口存在的问题 如下图所示: 我们假设这个固定窗口的大小为1,也就是每次只能发送一个数据,只有接收方对 ...
- 互联网协议 — TCP — 滑动窗口
目录 文章目录 目录 TCP ARQ 协议 TCP 的滑动窗口 Sender 滑动窗口 Receiver 滑动窗口 滑动窗口处理流程 窗口探测 TCP ARQ 协议 ARQ(Automatic Rep ...
- TCP三次握手、糊涂窗口、粘包问题
这是在学习中的总结,若有错误请大家不吝指正(^.^) 关于TCP/IP的三次握手: 当服务端的状态为LISTEN,客户端的状态为CLOSED时,客户端发起连接 客户端发送有SYN字段报文,此时状态为S ...
- TCP接收窗口--确定Window
1. TCP接收窗口的调整 在上面配置的rcv_buf都是配置的接收缓存,在tcp层中接收窗口不能完全占满接收缓存,因为TCP层描述的接收窗口,仅仅是tcp层的data,不包含整个数据包的heade ...
最新文章
- 苹果设备iphone,ipad,macbook网络连接慢,开机开什么卡什么,一步解决
- 第 十 天 : 添 加 硬 盘 和 分 区 挂 载 等
- java基本数据类型自动转包装类,Java String和基本数据类型之间的转换(包装类)
- python xlwt xlrd 写入一行_Python Excel文件的读写操作(xlwt xlrd xlsxwriter)
- 【第二章】 IoC 之 2.1 IoC基础 ——跟我学Spring3
- 【理论】数据结构----树的基本概念
- PAT甲级1054 map的使用
- 周末休息整理B站项目过于敏感,2h后删!
- Nginx中保持长连接的配置 - 运维记录
- android studio 跳转后保留原页面数据_这些技巧和习惯,让你的原生 Android 手机更好用(上篇)...
- 证件照换底(红→蓝)
- 好心情:22个表达好心情的经典句子,送给抑郁焦虑的你
- 王逸凡的十万个为什么
- 视觉检测零件同轴度 测试零件同轴度,检测是否同心圆
- 解放前端工程师——手把手教你开发自己的自定义列表和自定义表单系列之一缘起
- iOS OC mvvm开发模式
- 10.Java面向对象进阶2
- suspend(挂起)和resume(继续执行)线程
- 记录若干`tf.py_function`的使用的方式,便于查阅
- 舆情监测系统对企业有什么作用,企业如何监测网络舆情危机?
热门文章
- Python基础复习--print()函数、转义符、变量命名
- Spring Boot 使用 Swagger3 生成 API 接口文档
- 首次使用Neptune3000海底静力触探CPT记录
- LayUI使用Echarts实现统计图
- Bio::DB::GenBank, Bio::SeqIO
- 《上海市居住证》积分申请基本流程
- vue进入浏览器大屏
- Libgdx slg游戏进程记录
- 如何引导回购和好评且不被平台抽查和处罚
- matlab和saber哪个好用,实例分析 saber与simulink谁更适合仿真