Colderleo's blog Colderleo's blog
首页
Linux
C++
Python
前端
工具软件
mysql
索引
关于
GitHub (opens new window)

Colder Leo

热爱代码的打工人
首页
Linux
C++
Python
前端
工具软件
mysql
索引
关于
GitHub (opens new window)
  • 常见程序性能开销cost、latency延迟耗时的经验值
  • 面试常见问题
  • 静态链接-动态链接-elf详解-elfloader
  • 动态库和静态库的依赖问题
  • glibc和ld的编译调试-为某程序单独设置ld
  • dl_iterate_phdr遍历linkmap头、获取so加载地址
  • shell、bash语法和脚本模板
  • so文件查找路径
  • 逻辑地址-线性地址or虚拟地址-物理地址
  • 通过ELF读取当前进程的符号表并获取符号的版本信息
  • 虚拟内存,cache,TLB,页表
  • 用户内存空间分布和mmap
  • numa网卡绑定
  • 隔核绑核、服务器优化
  • popen底层原理和仿照实现-execl
  • tmux用法
  • ASLR机制
  • 程序后台运行、恢复前台nohup
  • 大页内存huge_page
  • 用perf查看page-fault
  • Bash设置显示全部路径
  • 查看socket fd状态,设置nonblock
  • cout输出到屏幕的过程
  • 多进程写同一文件-write原子性-log日志
  • vim用法
  • epoll用法
  • signal信号、软中断、硬中断、alarm
  • 内核模块
  • 读写锁之pthread_rwlock和内核rwlock自旋读写锁
  • systemtap
  • xargs、awk用法
  • openssl libssl.so.10.so缺失问题
  • netstat用法
  • fork函数
  • tcp延迟确认ack
    • 为什么要引入TCP延迟确认?内核如何实现?有哪些相关的算法,其内涵是什么?
  • 90.centos7上一次std-string编译错误定位
  • docker用法
  • find用法
  • dmesg
  • gcc编译用法
  • avx-sse切换惩罚
  • Centos7防火墙
  • chmod用法
  • kernel-devel安装版本
  • Linux-Centos7系统安装、网络设置、常见报错
  • linux下g++编译c++文件
  • MegaCli 安装及使用
  • mysql
  • mysql忘记密码修改方法
  • set用法
  • crontab
  • ssh传文件scp
  • ssh连接
  • tcpdump、tshark、tcpreplay用法
  • ubantu root登录以及创建新用户
  • ubuntu安装g++和gdb
  • uClibc编译失败解决方法
  • win10安装WSL open-ssh
  • yum升级git
  • 比较so文件版本-md5sum
  • 查看磁盘信息
  • 合并两个硬盘,挂载到一个文件夹下
  • 软件安装目录usr-local-src
  • 下载centos历史版本
  • sh脚本转可执行文件、加密
  • Linux
gaoliu
2022-07-17
目录

tcp延迟确认ack

# 为什么要引入TCP延迟确认?内核如何实现?有哪些相关的算法,其内涵是什么?

可以通过设置socket参数TCP_NODELAY来完全避免延迟确认吗?如何调整或关闭系统性的延迟确认?什么情况下ack会立即发送?

1.为了解决SWS(silly window syndrome,低能窗口综合症),例如在极端情况下,接收窗口只有一个字节,发送方发送一个字节随即被确认,窗口归0,随后接收方读取完一个字节,更新接收窗口为1,发送方继续发送一个字节,由此往复造成了很大的带宽开销,因此引入了延迟确认。 2.linux内核的实现方案是将确认和窗口更新延迟一段时间(redhat定义默认初始值为40ms,随后根据连接的重传超时时间(RTO)、上次收到数据包与本次接收数据包的时间间隔等参数进行不断调整。可通过修改tcp_delack_min,调整系统级别的最小延迟确认时间)希望在此期间能获取一些数据从而免费搭载出去。 3.尽管延迟确认减少了接收端给网络带来的负载,但是发送端发送多个小数据包的方式仍然低效,避免这种用法的一种算法是Nagle算法,其实现思路是: (1)如果包长度达到MSS,则允许发送; (2)如果该包含有FIN,则允许发送; (3)设置了TCP_NODELAY选项,则允许发送; (4)未设置TCP_CORK选项时,若所有发出去的小数据包(包长度小于MSS)均被确认,则允许发送; (5)上述条件都未满足,但发生了超时(一般为200ms),则立即发送。 Nagle算法只允许一个未被ACK的包存在于网络,它并不管包的大小,因此它事实上就是一个扩展的停-等协议,只不过它是基于包停-等的,而不是基于字节停-等的。Nagle算法完全由TCP协议的ACK机制决定,这会带来一些问题,比如如果对端ACK回复很快的话,Nagle事实上不会拼接太多的数据包,虽然避免了网络拥塞,网络总体的利用率依然很低。使用TCP_NODELAY选项可以禁止Negale 算法。 cork算法: 所谓的CORK就是塞子的意思,形象地理解就是用CORK将连接塞住,使得数据先不发出去,等到拔去塞子后再发出去。设置TCP_CORK选项后,内核会尽力把小数据包拼接成一个大的数据包(一个MTU)再发送出去,然而,由于内核并不知道应用层到底什么时候会发送第二批数据用于和第一批数据拼接以达到MTU的大小,因此内核会给出一个时间限制(一般为200ms),在该时间内没有拼接成一个大包(努力接近MTU)的话,内核就会无条件发送。也就是说若应用层程序发送小包数据的间隔不够短时,TCP_CORK就没有一点作用,反而失去了数据的实时性。 clark: nagle试图解决发送端每次只发送一个字节的问题,而clark则是要解决接收端应用每次只从TCP流中只读取一个字节而引发的问题,其解决方案是禁止接收端发送只有1个字节的窗口更新,相反,它强制接收端必须等待一段时间,知道有了一定数量的可用空间之后再通告给对方。特别是,只有接收端能够处理它在建立连接时宣告的最大数据段,或者它的缓冲区一半为空时(相当于两者之中取较小的值),它才发送窗口更新段。 4.由上述可知,设置TCP_NODELAY选项只能禁用nagle,系统性的延迟确认依然存在 5.2中提到,可以设置tcp_delack_min为1将延迟时间最低降至1ms,另外设置TCP_QUICKACK选项可以立即确认,但该选项不是永久的,必须在每次recv()之后重新设置。 6.linux下socket有一个pingpong属性来表明当前链接是否为交互数据流,如其值为1,则表明为交互数据流,会使用延迟确认机制。但是pingpong这个值是会动态变化的。还有一个quick属性,其代码中的注释为:scheduled number of quick acks,即快速确认的包数量,每次进入quickack模式,quick被初始化为接收窗口除以2倍MSS值,每次发送一个ACK包,quick即被减1。 满足以下两个条件则为QUICK模式,ack会立即发送 1).pingpong被设置为0。 2).快速确认数(quick)必须为非0。

编辑 (opens new window)
上次更新: 2023/04/30, 10:33:10
fork函数
90.centos7上一次std-string编译错误定位

← fork函数 90.centos7上一次std-string编译错误定位→

最近更新
01
通过模板实现结构体成员拷贝-按成员名匹配
05-07
02
c++17通过模板获取类成员的个数
05-01
03
avx-sse切换惩罚
04-30
更多文章>
Theme by Vdoing | Copyright © 2019-2023 Colder Leo | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×