TCP头部
- 一个TCP连接由一个4元组组成,由一对套接字构成,套接字是由IP地址和端口组成的,被称为socket;每个TCP连接由一对套接字唯一的标识
- 序列号字段唯一的标识了TCP发送端到TCP接收端的数据流的一个字节,代表报文段的数据中的第一个字节,处理被传送分组的重复和传送顺序。基于窗口的流量控制,窗口大小可以随时间变化,称为窗口通告,接收方的窗口通告夹带着发送方的窗口大小值
- 确认号字段是发送方期待接收的下一个序列号加1,这个字段只有在ACK位字段被启用的情况下才有效,选择确认选项高速发送方正确接收到次序杂乱的数据
- 头部长度限制了TCP至多只能携带60位的头部
- 16位限定了窗口大小至多65535字节,限制了TCP的吞吐量性能。定义分组窗口作为已发送还未被接收的分组的集合,窗口大小是分组数量,ACK反向流动
- ACK表示确认号是否有效,TCP使用的ACK是累积的,1)是否接收到分组;2)接收方接收到的是否和发送方发送的一致
- PSH表示接收端应用程序应立即从TCP接收缓冲区中读走数据;RST表示要求对方对方重新建立连接;SYN表示请求建立一个连接;FIN表示通知对方本端要关闭连接了
- TCP校验和字段覆盖了TCP的头部和数据以及头部中的一些字段,TCP会丢弃一个带无效校验和的报文段
- 紧急指针只在URG字段被设置时才有效,是必须被加到报文段的序列号字段上的正偏移,产生紧急数据的最后一个字节的序列号。这是发送方提供给另一端的特殊标志数据的方法
- 最常见的选项字段是最大段大小选项称为MSS,连接的每个端点基本上都在它发送的第一个报文段上指定这个选项,指定接收方希望接收到的报文段的最大值
- SO_RESEADDR可以用来设定端口释放后可以立即被使用;位于TIME_WAIT状态的套接字重复绑定使用,server程序在bind()之前设置这个TCP选项
- SO_LINGER可以改变close的行为
1 | struct linger{ |
TCP的连接和终止
- TCP的连接和终止分别对应著名的三次握手和四次挥手
三次握手
四次挥手
TCP拥塞机制
- 慢开始、拥塞避免、快速重传、快速恢复
- 发送方维护拥塞窗口cwnd,开始时cwnd=1,每经过一个RTTcwnd+1,每次传输轮次后cwnd按指数增长
- 慢开始门限ssthress,当cwnd>ssthress时,执行拥塞避免算法,cwnd线性增长
- 网络拥塞时,将ssthress设为原来的一半,cwnd重置为1
- 快速重传要求对方接收到一个失序报文断后立即发出重复确认,发送方持续受到三个重复确认就将ssthress减半,但不执行慢开始算法,将cwnd设为ssthress
- 滑动窗口
- 发送窗口收到对端窗口内字节的ACK确认才会移动窗口的左边界
- 应用程序通过API通知TCP协议栈缩小TCP接收窗口,对端按照通知的窗口来改变发送窗口
- 重传超时时间RTO
- 自适应重传算法:按照当前RTT的准确估计来调整RTO
- karn算法:新RTO=γ*旧RTO,γ典型值为2
- 不再重传时,更新平均RTT和重传时间的数值