滑动窗口(sliding window)

滑动窗口是用于流量控制的,发送端根据接收端的处理能力发送数据,不至于造成过多的丢包。 是发送方和接收方间的协调,对方的接收窗口大小就是自己的发送窗口大小。
在TCP头中有一个字段window,这个字段就是接收端告诉发送端自己还有多少缓冲区可以接收数据。发送端根据这个字段的值来发送数据,当值为0时就停止发送。
发送端和接收端各自维护着一个窗口,发送的滑动窗口控制可以发送的数据大小,接收端的窗口控制可以接收数据的大小。

发送端:LastByteAcked指向已经被成功接收的位置,LastByteSent指向最后已发送出去的位置,usable window表示发送端还可以发送的数据大小。如上图,发送端还有5个单位数据还未被ack,还可以再发送7个单位的数据。


接收端:LastByteExpected指向接收端收到的连续包的最后一个位置,LastByteRcvd指向收到的包的最后一个位置,waited come表示期望收到的包序列,waited read表示在缓冲区中还未读走的数据,usable window表示缓冲区还能接受的大小。如上图,缓冲区还能接受7个单位的数据,就会把7赋值给tcp头中的window字段。

发送端当收到window为0时,就停止发送数据,会陆续发送3次ZWP(zero window probe)询问接收端是否有可用窗口,接收端会回复可用窗口,如果3次都为0,发送端可能中断链接。

拥塞控制

滑动窗口用于流量控制,避免发送超过接收端处理能力的数据,导致数据丢失,是两端之间的协调。
拥塞控制是TCP用于发送端和网络情况间的协调,和慢启动一起避免恶化网络状况。根据网络延时情况,确定可发送窗口大小。这就抽象出一个拥塞窗口(congestion window)的概念,其最大值是发送窗口大小。
TCP有四个算法来动态调节拥塞窗口(cwnd)大小:

  • 慢启动
    连接建立时,cwnd=1
    cwnd线性上升,每收到一个ACK,cwnd++
    cwnd指数上升,每过一个RTT(round trip time),cwnd = cwnd * 2

  • 拥塞避免
    当cwnd>=ssthresh(slow start threshold),进入拥塞避免,cwnd的增加算法改成如下:
    每收到一个ack,cwnd=cwnd + 1/cwnd,基本不增加
    每过一个RTT,cwnd=cwnd + 1,在一个往返时间内最多为 cwnd增加 1 个报文段

  • 拥塞发生(超时RTO,丢包-重复收到同一个包的ACK)
    ssthresh = cwnd/2
    cwnd = 1,发送端基本不发送数据了。开始了慢启动的过程。

  • 快速恢复
    TCP为保证数据达到有两种重传算法,超时重传和快速重传。超时重传是等待RTT时间没收到ack,则重传;快速重传是接收端配合,接收端每收到一个tcp segment,返回的都是收到的连续序列的下一个序号,发送端收到3次同样的序号就进行重传。
    快速恢复通常和快速重传一起使用,如果接收端还能收到重复的ACK,说明收发两端还有数据流动。所以没必要反映那么强烈,不需要把cwnd降为1,可以缓和点减少流量,不进入慢启动。这是快速恢复的思想。
    1) 当收到第 3 个重复的 ACK时(认为拥塞发生),将 ssthresh设置为当前拥塞窗口 cwnd的一半。重传丢失的报文段。设置cwnd为ssthresh加上3倍的报文段大小。
    2) 每次收到另一个重复的 ACK时, cwnd增加 1个报文段大小并发送 1 个分组(如果新的cwnd允许发送)。
    3) 当下一个确认新数据的ACK到达时,设置 cwnd为ssthresh(在第1步中设置的值)。这个ACK应该是在进行重传后的一个往返时间内对步骤 1 中重传的确认。另外,这个ACK也应该是对丢失的分组和收到的第 1 个重复的 ACK之间的所有中间报文段的确认。这一步采用的是拥塞避免,因为当分组丢失时我们将当前的速率减半。
    总结下,收到重复的ack时,窗口和阈值减半,进入拥塞避免,试探性的重发丢失的报文段,直到无窗口可用或者拥塞消除。

注:网络实际传输受slidingwnd和cwnd控制,TCP能传输的最大数据 = MIN(slidingwnd, cwnd)
参考TCP的那些事儿(下)http://coolshell.cn/articles/11609.html

Linux网络编程系列-TCP传输控制的更多相关文章

  1. linux网络编程系列-TCP/IP模型

    ### OSI:open system interconnection ### 开放系统互联网模型是由ISO国际标准化组织定义的网络分层模型,共七层 1. 物理层:物理定义了所有电子及物理设备的规范, ...

  2. Linux网络编程系列-TCP编程实例

    实例: client #include <stdio.h> #include <sys/socket.h> #include <netinet/in.h> #inc ...

  3. 【Linux网络编程】TCP网络编程中connect()、listen()和accept()三者之间的关系

    [Linux网络编程]TCP网络编程中connect().listen()和accept()三者之间的关系 基于 TCP 的网络编程开发分为服务器端和客户端两部分,常见的核心步骤和流程如下: conn ...

  4. 【Linux 网络编程】TCP网络编程中connect()、listen()和accept()三者之间的关系

    基于 TCP 的网络编程开发分为服务器端和客户端两部分,常见的核心步骤和流程如下: connect()函数:对于客户端的 connect() 函数,该函数的功能为客户端主动连接服务器,建立连接是通过三 ...

  5. Linux网络编程系列-套接口选项控制

    获取和设置套接口选项的方法有: getsockopt/setsockopt fcntl ioctl getsockopt/setsockopt 这两个函数仅用于套接口(socket)的设置,另外两个函 ...

  6. linux网络编程笔记——TCP

    1.TCP和UDP TCP是长连接像持续的打电话,UDP是短消息更像是发短信.TCP需要消耗相对较多的资源,但是传输质量有保障,UDP本身是不会考虑传输质量的问题. 2.网络传输内容 我习惯的做法是直 ...

  7. Linux网络编程学习(二) ----- 进程控制(第三章)

    1.进程和程序 程序是一个可执行文件,而一个进程是一个执行中的程序实例.一个进程对应于一个程序的执行,进程是动态的,程序是静态的,多个进程可以并发执行同一个程序.比如几个用户可以同时运行一个编辑程序, ...

  8. Linux 网络编程系列教程

    一.基础理论篇 01.网络协议入门 02.LAN.WAN.WLAN.VLAN 和 VPN 的区别 03.IP 地址介绍 04.广播地址介绍 05.无连接和面向连接协议的区别 06.因特网的IP协议是不 ...

  9. linux网络编程之断点传输文件

    以下载链接"http://www.boa.org/boa-0.94.13.tar.gz"为例: 断点续传实验大概步骤: ===================== 1,使用geth ...

随机推荐

  1. ssh整合,导入structs包后报错 getAnnotation(AnnotatedElement ae,Class<T> annotatetype)找不到

    今天在整合ssh(spring-framework-3.2.5.RELEASE-dist+struts-2.3.15.3-all+hibernate-release-4.2.6.Final)环境的时候 ...

  2. Stack Overflow is a question and answer site

    http://stackoverflow.com/ _ Stack Overflow is a question and answer site for professional and enthus ...

  3. 8421BCD码转换为十进制

    这个转换和随意的认知是不同的,要了解BCD码和二进制码的区别 #define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10) ...

  4. AVL-tree

    //avl.h#ifndef __AVL_H__#define __AVL_H__ typedef int KEY_TYPE; /* struct */typedef struct AVL{ KEY_ ...

  5. lua 位运算

    bit = {data32={}} , do bit.data32[i] = ^(-i) end function bit:d2b( arg ) local num = tonumber( arg ) ...

  6. 【原创】初识懒人开发库---ButterKnife

    今天再看别人代码的时候,看到了自己没见过的代码,看起来挺方便的,具体代码如下: @InjectView(R.id.iv_left) ImageView iv_left; @InjectView(R.i ...

  7. mysql mHA manager 状态修改

    启动:nohup masterha_manager --conf=/etc/masterha/app1.cnf --remove_dead_master_conf --ignore_last_fail ...

  8. sqlserver和oracle的递归查询

    1.sqlserver递归查询方式 CTE: if OBJECT_ID('tb','N') is not null   drop table tb;     create table tb(id va ...

  9. 【开发环境】JAVA 环境变量批处理

    @echo off set regpath=HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environmen ...

  10. 「2014-3-18」multi-pattern string match using aho-corasick

    我是擅(倾)长(向)把一篇文章写成杂文的.毕竟,写博客记录生活点滴,比不得发 paper,要求字斟句酌八股结构到位:风格偏杂文一点,也是没人拒稿的.这么说来,arxiv 就好比是 paper 世界的博 ...