10 理解tcp的写操作
10.1 从用户层看写操作
- 用户程序对一条tcp连接进行写调用时,首先会将数据从用户缓冲区赋值到内核中去,当send返回时(除非tcp发送缓冲区满了,否则写操作是不会被阻塞的),具体发送了多少数据依赖于连接状态.
- 写操作很少向tcp返回错误.因此,常见错误通常由读操作返回,写操作只返回写调用时发生的明显错误,如下:
- 套接字描述付无效
- 文件描述符指向的不是套接字
- 调用中指定的套接字不存在或未连接
- 缓冲区地址参数指向无效地址
EPIPE或SIGPIPE是个例外,连接被对等实体重置时也会出现这种错误.
10.2 从内核层看写操作
- tcp在任意时刻能够发送的最大数据量是发送和拥塞窗口中的最小值,发送窗口由对等实体tcp控制,防止我们发送的数据使对等实体的缓冲区溢出.拥塞窗口由我们的tcp控制,防止我们发送超出网络容量的数据.
- 第一种流量控制算法被称为慢启动,慢慢的将网络数据的速率增加到一个门限值.
- 另一个影响tcp发送策略的因素是Nagle算法.算法指出,在任意指定的时刻,未被确认的小段(长度小于MSS)不能超过一个.算法目的是防止tcp用一系列的小段来充斥网络,tcp会将数量较小的数据保存起来,直到接收到对前一个小段的ACK为止,然后将数据一次性地发送出去.
- 发送窗口是对对等实体可用缓存区空间的估计.对等实体在其发送的每个段中都包含了窗口更新,以此来告知当前可用缓冲区空间的容量.接收端的SWS(Silly Window Syndrome)避免算法包括不宣告缓冲区的少量增长.(RFC1122需要一个全尺寸段地增长,或大于窗口最大长度的一半,BSD派生的实现则要求两个全尺寸段或一个半最大窗口的增长).
- 只要调用tcp输出例程,它就会根据发送缓冲区,发送窗口长度,拥塞窗口长度和MSS中的最小值计算可以发出的数据量,满足下列某一项,数据就会被传送出去:
- 可以发送一个完整MSS尺寸的段
- 连接空闲,并且可以清空发送缓存区
- Nagle算法被禁止,并且可以清空发送缓存区
- 由紧急数据需要发送
- 有一小段"暂时"无法发送的数据(定时器5-60s)
- 对等实体的接收窗口至少是半开的
- 需要重传一个段
- 需要为来自对等实体的数据回送一个ACK
- 需要发布一次窗口更新