前面的文章分析了接收端如何发送ack给发送端,总结一下就是立即ack,捎带ack和延迟ack,现在看一下tcp的发送端是如何处理ack的,本质上tcp所谓的有连接就是双方对于seq和ack的处理,对于seq,发送方是主动的,而接收端是被动的,但是对于ack则相反,因此参照tcp的流控以及拥塞控制加之性能因素的需要,首先要设计接收端如何发送ack,其次再来设计发送端如何处理,linux采纳了rfc的建议(好像没有不采纳的OS,除非它猛到自己定义标准)。对于发送ack,前面已经说过了,对于如何处理ack,完全就是应付一下,要简单的多,简单的说,接收端只会发送按序报文的最后一个未被确认的报文的seq作为其ack,但是对于发送端收到这个ack后如何处理,虽然比发送ack的逻辑和策略要简单,但是也要彻底理解协议才能看懂代码:

static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag)

{

...

if (after(ack, tp->snd_nxt))

goto uninteresting_ack;

if (before(ack, prior_snd_una))

goto old_ack;

if (!(flag&FLAG_SLOWPATH) && after(ack, prior_snd_una)) { //非冗余的ack,正常,不进入快速重传

tcp_update_wl(tp, ack, ack_seq);

tp->snd_una = ack;

tcp_westwood_fast_bw(sk, skb);

flag |= FLAG_WIN_UPDATE;

} else {

if (ack_seq != TCP_SKB_CB(skb)->end_seq) //说明是捎带ack

flag |= FLAG_DATA;

flag |= tcp_ack_update_window(sk, tp, skb, ack, ack_seq); //flag可能置update位

if (TCP_SKB_CB(skb)->sacked) //如果是sack,则说明可能丢包了,有可能置上sack位,选择确认接收端已经收到的报文,sack完全是为了提高性能的,实际上在分析代码的时候可以忽略这种情况,只有确认丢失报文的时候才会选择确认(sack)

flag |= tcp_sacktag_write_queue(sk, skb, prior_snd_una);

if (TCP_ECN_rcv_ecn_echo(tp, skb->h.th)) //路由器通知丢包,置上ece位

flag |= FLAG_ECE;

...

}

...

flag |= tcp_clean_rtx_queue(sk, &seq_rtt); //尽量清除所有已经被确认的报文,如果有被确认的报文,则置上acked位

...

if (tcp_ack_is_dubious(tp, flag)) { //如果没有设置acked位,也没有设置data位也没有设置update位,或者存在sack或者ece位,则说明可能已经丢失报文,这里判断比较复杂,注意||运算符,只要第一个比较对象返回真就返回,依次类推,flag如果有data位或者acked位,我们也不能确定就一定没有丢失报文,因为ack由对端发送,可能的方式有好几种,不仅仅是裸ack,还可能是捎带ack,对于设置了acked位的flag也不能说就一定没有丢失报文,因为虽然该ack确认一部分报文,但是后面的报文可能丢失,复杂的情况下还可能出现选择确认-sack,因此还需要进一步判断ece和sack标志,但是反过来可以说的是,如果既没有data位,也没有acked位,也没有update位,则一定要进入重传。

...//进入拥塞控制,快速重传

tcp_fastretrans_alert(sk, prior_snd_una, prior_packets, flag);

}

...//否则正常返回

return 1;

...

}

其中最麻烦的就是sack的相关逻辑了,前面说了,sack完全是为性能考虑的一个可选的机制,它可以使得发送端只重传丢失的报文,而不必重传已经发来的有选择的乱序的确认报文,这是通过tcp头的选项进行配置的。使用sack机制前要允许sack选项,在冗余ack发来的时候,它携带一些信息,这些信息包含哪些乱序的报文已经安全正确接收且被暂存在接收端了,如此一来发送端重传报文的时候就不必再传输这些已经确认的乱序报文了,具体可以看一下tcp_sacktag_write_queue的代码。

linux tcp ack设置,linux关于tcp协议ack的实现--发送端对ack的处理相关推荐

  1. linux关于tcp协议ack的实现--发送端对ack的处理

    前面的文章分析了接收端如何发送ack给发送端,总结一下就是立即ack,捎带ack和延迟ack,现在看一下tcp的发送端是如何处理ack的,本质上tcp所谓的有连接就是双方对于seq和ack的处理,对于 ...

  2. 防火墙策略添加linux,通过iptables设置Linux防火墙INPUT策略

    原标题:通过iptables设置Linux防火墙INPUT策略 小白电脑课堂开课啦!游戏团战就死机,多半是废了.大家好我是小白.说到防火墙,同学们都会想到开了防火墙就会卡的Windows.而在Linu ...

  3. linux共享文件权限设置,linux – Windows更改Samba文件共享中的文件权限

    我安装了一个外部USB驱动器,用于CentOS上的文件共享.所有客户端访问共享都是Windows XP或7.在Windows中,我使用"用户帐户"中的"管理您的凭据&qu ...

  4. linux+ip+路由设置,Linux下IP巧设置-网管专栏,防火墙和路由

    如何实现ip伪装?假设你现在有一台linux主机通过ddn专线连接到internet上,有自己的ip和域名,同时还与20台win95工作站通过hub连接,你现在完全可以通过ip伪装来实现这20台win ...

  5. linux 系统swap设置,Linux 系统swap 设置

    1.打开终端,切换到root用户,输入:free -m查看内存状态 [root@lxt lxt]# free -m total used free shared buffers cached Mem: ...

  6. linux ssh 时间设置,Linux下设置SSH Server设置时间链接限制(示例代码)

    OpenSSH基于安全的理由,如果用户连线到SSHServer后闲置一段时间,SSH Server会在超过特定时间后自动终止SSH连线.本人习惯长时间连接,需要做如下修改: 1.打开ssh配置文件:# ...

  7. linux系统引导设置,Linux操作系统GRUB引导程序配置方法大全 - 技术文档 - 新手入门 Linux时代......

    1. GRUB 介绍 计算机在启动的时候,首先由BIOS中的程序执行自检,自检通过后,就根据CMOS 的配置找到第一个可启动磁盘的MBR中的Boot Loader程序(一般在启动盘的第一个物理扇区,占 ...

  8. linux还原防火墙设置,Linux防火墙设置

    Linux防火墙操作 1.重启后生效 ​ 开启: chkconfig iptables on ​ 关闭: chkconfig iptables off 2.即时生效 开启: service iptab ...

  9. linux sftp权限设置,Linux设置SFTP服务用户目录权限

    我们有时会遇到这样的需求,限制一个Linux用户,让他只能在指定的目录下进行添加.修改.删除操作,并且只能使用sftp登录服务器,不能用ssh操作.这些可以通过配置sftp服务实现. 提供sftp服务 ...

最新文章

  1. 案例 | 杭州佰勤医疗器械:智办事助力企业组织数字化转型
  2. python 3.7.3 thinker_GitHub - thinkerwalker/python3-bin
  3. caged系统pdf_建筑行业单词中英文对照教材.pdf
  4. LeetCode —— 365. 水壶问题(Python3)
  5. 关于×××隧道技术在使用中的优势
  6. 超大ISO文件的分卷刻录方法
  7. python和c 的区别-对比平台--C和Python之间的区别
  8. Pytorch的可视化工具tensorboardX
  9. RHEL/Centos下VSFTPD服务器搭建
  10. 一篇很感人的DOTA小说--我本近卫
  11. 天才少女谷爱凌夺金!母亲毕业于北大,父亲毕业于哈佛,她将入读斯坦福…...
  12. 上传应用到苹果一直卡住验证中(authentication with the app store)问题解决
  13. LINUX下浮点运算
  14. 论文分享——Dynamic graph attention for referring expression comprehension
  15. 做成事情的3个要素:意愿、能力、资源
  16. 希尔顿集团大中华区第450家酒店开业;Gap在山东青岛开新店 | 美通企业日报
  17. Python爬虫大众点评字体加密评论采集!听说这个网站很难?
  18. c#取消word修订痕迹_C# 操作Word批注(一) 插入、修改、删除Word批注
  19. Linux bash: redis-server: 未找到命令
  20. python中的sort排序加换行_python中sort()排序的方法

热门文章

  1. 由{% if %} 导致的jinja2.exceptions.TemplateSyntaxError: Encountered unknown tag
  2. java containsany_判断字符串中是否存在的几种方案:string.indexof、string.contains、list.contains、list.any几种方式效率对比...
  3. 如何将word文件名批量导入excel
  4. 一文彻底搞清git reset和revert区别
  5. html标签--隐藏域
  6. 自己怎么拍出好看的证件照?掌握这几点小诀窍就够了
  7. leetcode 495. 提莫攻击 C语言版
  8. Gstreamer编译
  9. CCF CTO Club 16期活动记事——走进腾讯,实现连接
  10. android如何打开工程文件夹,Android工程目录结构介绍