在tcp_clean_rtx_queue()中,并非对每个ACK都进行时延采样.是否进行时延采样,跟这个ACK是否为 重复的ACK.这个ACK是否确认了重传包,以及是否使用时间戳选项都有关系. 本文主要内容:tcp_clean_rtx_queue()的一些细节,时延采样的条件. 内核版本:3.2.12 Author:zhangskd @ csdn 记分牌 TCP_SKB_CB(skb)->sacked称为skb的记分牌,用于跟踪skb的状态. 以下是skb记分牌可能的取值: #define TC…
重传队列实际上就是发送队列(sk->sk_write_queue),保存着发送且未确认的数据段. 当有新的数据段被确认时,需要把这些段从重传队列中删除,同时更新一些变量,包括 packets_out.sacked_out.lost_out.retrans_out等. 对于非重复的ACK,会进行RTT采样,用于更新srtt和rto等时延信息. 本文主要内容:tcp_clean_rtx_queue()的实现. 内核版本:3.2.12 Author:zhangskd @ csdn 函数实现 Q:什么是…
TCP发送数据包后,会收到对端的ACK.通过处理ACK,TCP可以进行拥塞控制和流控制,所以 ACK的处理是TCP的一个重要内容.tcp_ack()用于处理接收到的ACK. 本文主要内容:TCP接收ACK处理,tcp_ack()的实现. 内核版本:3.2.12 Author:zhangskd @ csdn 基础 在我们开始探究tcp_ack()的处理流程前,不妨先来回顾一些即将涉及到的概念和数据结构. struct tcp_sock { ... /* Packets which are "in…
18版本对于每个SACK块,都是从重传队列头开始遍历.37版本则可以选择性的遍历重传队列的某一部分,忽略 SACK块间的间隙.或者已经cache过的部分.这主要是通过tcp_sacktag_skip()和tcp_sacktag_walk()完成的. tcp_sacktag_skip()可以直接找到包含某个序号的skb,通常用于定位SACK块的开头. tcp_sacktag_walk()则遍历两个序号之间的skb,通常用于遍历一个SACK块. 本文主要内容:SACK的遍历函数tcp_sacktag…
TCP的实现中,SACK和DSACK是比较重要的一部分. SACK和DSACK的处理部分由Ilpo Järvinen (ilpo.jarvinen@helsinki.fi) 维护. tcp_ack()处理接收到的带有ACK标志的数据段时,如果此ACK处于慢速路径,且此ACK的记分牌不为空,则调用 tcp_sacktag_write_queue()来根据SACK选项标记发送队列中skb的记分牌状态. 笔者主要分析18和37这两个版本的实现. 相对而言,18版本的逻辑清晰,但效率较低:37版本的逻辑…
和18版本相比,37版本的SACK和DSACK的实现做了很多改进,最明显的就是需要遍历的次数少了, 减少了CPU的消耗.37版的性能提升了,代码有大幅度的改动,逻辑也更加复杂了. 本文主要内容:37版tcp_sacktag_write_queue()的实现,也即37版SACK和DSACK的实现. Author:zhangskd @ csdn 数据结构 /* This defines a selective acknowledgement block. */ struct tcp_sack_blo…
我们发送重传包时,重传包也可能丢失,如果没有检查重传包是否丢失的机制,那么只能依靠超时来恢复了. 37版本把检查重传包是否丢失的部分独立出来,这就是tcp_mark_lost_retrans(). 在处理SACK块的同时,会检测是否有出现乱序,如果有乱序,那么会计算乱序的长度并更新. 本文主要内容:检查重传包是否丢失,以及乱序的检测和更新. Author:zhangskd @ csdn 检查重传包是否丢失 tcp_mark_lost_retrans()用于检查重传的包是否丢失,2.6.22内核在…
上篇文章中我们主要说明如何skip到一个SACK块对应的开始段,如何walk这个SACK块包含的段,而没有涉及到 如何标志一个段的记分牌.37版本把给一个段打标志的内容独立出来,这就是tcp_sacktag_one(). 本文主要内容:tcp_sacktag_one(),给一个段打上标志. Author:zhangskd @ csdn 标志一个包 tcp_sacktag_walk()用于遍历块中的数据包,最终会调用tcp_sacktag_one()来标志一个数据包的记分牌, 即TCP_SKB_C…
和18版本不同,37版本把DSACK的检测部分独立出来,可读性更好. 37版本在DSACK的处理中也做了一些优化,对DSACK的两种情况分别进行处理. 本文主要内容:DSACK的检测.DSACK的处理. Author:zhangskd @ csdn dsack检测 根据RFC 2883,DSACK的处理流程如下: 1)look at the first SACK block : -If the first SACK block is covered by the Cumulative Ackno…
本文主要内容:tcp_ack()中的一些细节,如发送窗口的更新.持续定时器等. 内核版本:3.2.12 Author:zhangskd @ csdn 发送窗口的更新 什么时候需要更新发送窗口呢? (1)确认了新的数据 (2)条件1不成立,ACK段的序号是最新的. 这表示虽然ACK段没有确认了新的数据,但是它携带了新数据. (3)条件1和2都不成立,通告窗口变大. ACK既没有确认了新的数据,序号也不是最新的. 虽然如此,但是如果对端的接收窗口变大,我们还是要更新发送窗口. 此时ack_seq必须…
不论是18版,还是37版,一开始都会从TCP的控制块中取出SACK选项的起始地址. SACK选项的起始地址是保存在tcp_skb_cb结构的sacked项中的,那么这是在什么时候做的呢? SACK块并不是总是合法的,非法的SACK块可能会引起处理错误,所以还需要进行SACK块的合法性检查. 本文主要内容:TCP首部中SACK选项的解析和地址的获取,SACK块的合法性检查. Author:zhangskd @ csdn SACK选项的地址 TCP_SKB_CB(skb)->sacked is in…
从Linux源码看Socket(TCP)的listen及连接队列 前言 笔者一直觉得如果能知道从应用到框架再到操作系统的每一处代码,是一件Exciting的事情. 今天笔者就来从Linux源码的角度看下Server端的Socket在进行listen的时候到底做了哪些事情(基于Linux 3.10内核),当然由于listen的backlog参数和半连接hash表以及全连接队列都相关,在这一篇博客里也一块讲了. Server端Socket需要Listen 众所周知,一个Server端Socket的建…
作为TCP的重头戏,本章节涉及了许多关于计算方面的内容,使用了大量的例子来指明一些观点. 我使用的理解方法是:通过别人的博客,以及实例结合进行理解,不然会很吃力. 21.1 引言 reliable TCP提供可靠的运输层,它使用的方法之一就是确认从另外一端收到的数据. 也就是说通过ACK,或者说 TCP自时钟,来保证这一特性. TCP通过在发送的时候,设置一个定时器来解决这些问题.如果当定时器溢出还没有收到确认,就重传数据,对于任何的实现而言,关键就在超时和重传的策略. 四个不同的定时器 重传定…
友好的视觉感知和稳定的不出错表现,来自于我们追求美感和考虑的全面性,博客园从技术的角度,一直我都很欣赏.这篇文章是android开发人员的必备知识,是我特别为大家整理和总结的,不求完美,但是有用. 这一篇是对上一篇<Android学习系列(2)--App自动更新之通知栏下载>的补充,因此只是以点为要,点到为止.1.内部存储    出于考虑到用户可能禁掉了SDCard或者电脑暂时插在电脑上且为磁盘连接状态等等,对于这么个情况下,我们应该也要保证我们的程序也是能正常的运行.所以我们要考虑内部存储.…
TCP的阻塞和重传机制 网络拥堵 现在网络上大部分的网络请求都是以TCP的方式进行传输的了.网络链路是固定的,各种链路情况也是不一样的.网络拥堵一直是TCP协议设计和使用的时候尽力要避免的.比如,从TCP协议的网络包协议设计来看,TCP使用一发一答的ACK的网络包确认方式,而不是使用NAK这种会增加确认包的方式来做确认机制.这个就是在尽力降低网络上的包传递数量,避免网络拥堵. 还有哪些控制网络拥堵的方式呢? 慢启动 当一个连接连接上网络的时候,并不应该一次向网络中就发送大量的数据包,否则的话,如…
艺萌TCP文件上传下载及自动更新系统介绍(TCP文件传输) 该系统基于开源的networkComms通讯框架,此通讯框架以前是收费的,目前已经免费并开元,作者是英国的,开发时间5年多,框架很稳定. 项目地址:http://www.51aspx.com/code/MSDCArtMengFileUpload 咨询qq:286275658 演示程序下载地址:http://pan.baidu.com/s/1geVfmcr 服务器端运行效果图: 服务器端配置文件: <?xml version="1.…
TCP的阻塞和重传 TCP的阻塞和重传机制 网络拥堵 现在网络上大部分的网络请求都是以TCP的方式进行传输的了.网络链路是固定的,各种链路情况也是不一样的.网络拥堵一直是TCP协议设计和使用的时候尽力要避免的.比如,从TCP协议的网络包协议设计来看,TCP使用一发一答的ACK的网络包确认方式,而不是使用NAK这种会增加确认包的方式来做确认机制.这个就是在尽力降低网络上的包传递数量,避免网络拥堵. 还有哪些控制网络拥堵的方式呢? 慢启动 当一个连接连接上网络的时候,并不应该一次向网络中就发送大量的…
本节书摘来自华章出版社<Microduino实战>一 书中的第2章,第2.3节,作者:姚琪 杨立斌,更多章节内容可以访问云栖社区"华章计算机"公众号查看. 2.3 Microduino STM32核心系列 除了兼容Arduino的核心模块,Microduino也提供了Microduino-CoreSTM32核心模块,采用 STM32F103CBT6芯片,是72MHz 32位的ARM微控制器,具和128KB Flash和20KB SRAM,如图2-7所示.该核心模块采用Upi…
主要内容:TCP定时器概述,超时重传定时器.ER延迟定时器.PTO定时器的实现. 内核版本:3.15.2 我的博客:http://blog.csdn.net/zhangskd Q:一条TCP连接会使用多少个定时器呢? A:目前的答案是9个: 超时重传定时器,持续定时器,ER延迟定时器,PTO定时器,ACK延迟定时器, SYNACK定时器,保活定时器,FIN_WAIT2定时器,TIME_WAIT定时器. 数据结构 几种定时器的标识: #define ICSK_TIME_RETRANS 1 /* R…
超时重传是TCP协议保证数据可靠性的另一个重要机制,其原理是在发送某一个数据以后就开启一个计时器,在一定时间内如果没有得到发送的数据报的ACK报文,那么就重新发送数据,直到发送成功为止. 1.超时 超时时间的计算是超时的核心部分,TCP要求这个算法能大致估计出当前的网络状况,虽然这确实很困难.要求精确的原因有两个:(1)定时长久会造成网络利用率不高.(2)定时太短会造成多次重传,使得网络阻塞.所以,书中给出了一套经验公式,和其他的保证计时器准确的措施. 1.1.递推公式概说 最早的TCP曾经用了…
21.1 引言 可靠性的保证之一就是超时重传 前面两个超时重传的例子 1)  ICMP端口不能到达时,TFTP客户使用UDP实现了一个简单的超时和重传机制,假定5s是一个适当是时间间隔,并每隔5s进行重传 2)  在向一个不存在的主机发送ARP的 例子中,可看到当TCP试图建立连接的时候,在每个重传之间使用一个较长的时延来重传SYN 对于每个连接,TCP管理4个不同的定时器: 1)  重传定时器使用于当希望收到另一端的确认 2)  坚持(persist)定时器使窗口大小信息保持不断流动,即使另一…
主要内容:保活定时器的实现,TCP_USER_TIMEOUT选项的实现. 内核版本:3.15.2 我的博客:http://blog.csdn.net/zhangskd 原理 HTTP有Keepalive功能,TCP也有Keepalive功能,虽然都叫Keepalive,但是它们的目的却是不一样的. 为了说明这一点,先来看下长连接和短连接的定义. 连接的"长短"是什么? 短连接:建立一条连接,传输一个请求,马上关闭连接. 长连接:建立一条连接,传输一个请求,过会儿,又传输若干个请求,最后…
/*ipv4_specific是TCP传输层到网络层数据发送以及TCP建立过程的真正OPS, 在tcp_prot->init中被赋值给inet_connection_sock->icsk_af_ops 这里面有每种协议传输层的接收函数,后面的inetsw_array那几行是套接口层的相关函数 在函数中执行handler,见函数ip_local_deliver_finish family协议族通过sock_register注册 传输层接口tcp_prot udp_prot netlink_pro…
RTT:往返时间:  RTO:Retransmission Timeout即超时重传时间: 关键点在于:超时和重传间隔的策略,即怎样确定超时间隔和重传间隔: TCP中的四个定时器:2MSL定时器:重传定时器:坚持定时器:保活定时器: 首先是如何得到RTO值:(假设已经能测量到RTT值情况下) RTO值是依赖RTT值来确定的:而鉴于网络环境的不稳定性,RTT总是变化的, RTT = 0.1*M  + 0.9*R;  M:当前测试的RTT值,R:历史RTT的值: RTO=@RTT:    @:一般取…
TCP提供可靠的运输层.它使用的方法之一就是确认从另一端收到的数据.但数据和确认都有可能会丢失.TCP通过在发送时设置一个定时器来解决这种问题.如果当定时器溢出时还没有收到确认,它就重传该数据. 对于实现而言,关键之处就在于超时和重传的策略,即怎样决定超时间隔和如何确定重传频率. TCP管理4种不同的定时器: 重传定时器:当希望收到另一端的确认时使用. 坚持定时器:使窗口信息保持不断流动,即使另一端关闭了其接收窗口. 保活定时器:检测一个空闲连接的另一端何时崩溃或重启. 2MSL定时器:测量一个…
tcp服务器在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接. 第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认; 第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态; 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入…
初码Azure系列文章目录 将消息队列技术模型简化,并打造成更适合互联网+与敏捷开发的云服务模式,好像已经是行业趋势,阿里云也在推荐使用消息服务(HTTP协议为主)而来替代消息队列(TCP协议.MQTT协议为主),并且将消息服务纳入到了存储体系内(Azure也是,有人知道为什么吗,是因为数据持久化在了磁盘上?) 更搞笑的是,阿里云还在帮助中心贴了一个表格 真是扎心了老铁,这不是自己怼自己,逼人用消息服务吗.. 回到本文主题上来,这几天用了Azure的存储服务里面的存储队列,感觉还是非常好用的,大…
主要内容:从TCP层面判断发送缓存的申请是否合法,进程因缺少发送缓存而进行睡眠等待. 因为有发送缓存可写事件而被唤醒. 内核版本:3.15.2 我的博客:http://blog.csdn.net/zhangskd TCP的发送缓存管理发生在两个层面上:单个Socket和整个TCP层. 上一篇blog讲述了单个Socket层面上的发送缓存管理,现在来看下整个TCP层面上的发送缓存管理. 从TCP层面判断发送缓存的申请是否合法 在申请发送缓存时,会调用sk_stream_memory_free()来…
主要内容:TCP发送缓存的初始化.动态调整.申请和释放. 内核版本:3.15.2 我的博客:http://blog.csdn.net/zhangskd 数据结构 TCP对发送缓存的管理是在两个层面上进行的,一个层面是单个socket的发送缓存管理, 另一个层面是整个TCP层的内存管理. 单个socket的发送缓存所涉及的变量. struct sock { ... /* 预分配缓存大小,是已经分配但尚未使用的部分 */ int sk_forward_alloc; ... /* 提交给IP层的发送数…
主要内容:Socket发送函数在TCP层的实现 内核版本:3.15.2 我的博客:http://blog.csdn.net/zhangskd 在上篇blog中分析了tcp_sendmsg()这个主要函数的实现,现在来看下之前略过的一些细节, 包括等待连接的建立.tcp_push()的实现.tcp_autocorking和数据的复制. 等待连接建立 在tcp_sendmsg()中如果发现连接尚未建立,会调用sk_stream_wait_connect()来等待连接的建立, 连接成功建立时返回0,之…