本篇转载于:http://blog.youkuaiyun.com/qingyixiaoxia 微信号:qingyixiaoxia 【内容有所删减。。。】
一 TCP和UDP
[一] 传输层概览
传输层基本特性:
1. 端到端传输:传输层协议部署于网络边缘的终端节点之上,为应用层提供端到端的数据传输服务。传输层提供的服务呈现为SOCKET接口,通过使用SOCKET接口应用层可以不用关心网络交换,路由等细节。
2. 多服务类型:传输层包括UDP和TCP两种服务类型,分别提供:
- 轻量尽力而为但不可靠的传输服务;
- 带有复杂可靠性机制的传输服务;
[二] TCP和UDP的对比:
[三] TCP特性概览:
二 TCP的静态特性
[一] TCP包结构
TCP包结构字段说明:
1) Sequence Number序列号 和 Acknowledgment Number确认号:
Sequence Number 序列号为当前传送的TCP包第一个字节在字节流中的偏移;
Acknowledgment 确认号为该数据包发送端期待的下一数据包的序列号,即对端发送的下一个数据包首字节在对端发送字节流中的偏移;
2) Window Size接收窗口大小:
该包发送方接收窗口余量。注意,接收窗口大小为65535 * N字节。
其中N是一个单位信息,由选项字段中的Window Scale来指定,且默认为1。
3) CWR/ECE/URG/ACK/PSH/RST/SYN/FIN标志位:
UAPSFR六个标志位指示了TCP数据包的类型。CWR和ECE用于拥塞控制。标志位可以多选。
- URG: 携带了紧急数据 (“紧急指针” 有效)
- ACK: 携带了确认序号 (“ACK序列号” 有效)
- PSH: 携带了用户数据 (“数据” 有效)
- SYN: 建链请求
- FIN: 断链请求
- RST: 复位指示
- CWR和ECE用于拥塞控制:
- CWR: 拥塞窗口减少 (发送方降速)
- ECE: 发送方收到早期拥塞通告
4) Options选项字段:
选项字段是一个变长字段,大小从0字节 - 40字节按需变化。常用的选项字段如下述:
- MSS:Max Segment Size 最大段大小。用于告诉对端本端期望的最大报文大小。
- WSOPT:Window Scale Option窗日缩放因子。用于控制滑动窗口的大小(滑动窗口大小是65535的WSPOT个倍乘数)。
- SACK-Permitted:发送者支持SACK选项。
- SACK:接收到乱序数据,用于确认。
[二] TCP端口号
TCP端口号说明:
传输层端口号,目的时将一对一的端到端,变成多对多的“点到点”。IP层是端到端的,而传输是每个端上最多65535个点到点的。是对唯一的网卡的复用和解复用。
[三] TCP字节流:
关于TCP字节流的说明:
1. 字节流VS数据报:
TCP面向字节流传输: TCP有发送buffer和接收buffer。应用层请求发送的数据不断放在TCP Socket发送buffer中,形成发送字节流。TCP对发送buffer 中的字节流做分段组包,并给与序号,之后递交给IP发送。数据到达接收端后,TCP将应用数据不断放入接收buffer,形成接收字节流。TCP对数据的发送和接收,均未对原始数据的“边界”做处理,而是视所有数据为一个源源不断的字节流。
UDP面向数据报传输: 应用层传来的数据,不予分段,直接交给IP发送。分段和重组的工作由IP完成。UDP发送端发送多大的数据,UDP接收端便一次性接收多大的数据。TCP对发送字节编号:编号变化区间为0 到 - 1。当SEQ到达- 1时,会重新从0开始编号。数据报的SEQ值:是本报文中携带的第一个数据字节在TCP发送字节流中的编号。
2. ACK的SEQ值:是发送端期待接收的下一报文的SEQ值,也即下一报文中第一个字节在对端发送流中的编号。
[四] TCP发送缓存和接收缓存
关于TCP接收缓存和发送缓存的说明:
1. Overall:数据被物理层接收后,每经过一层协议,剥离对应的头部,并将载荷递交给上层协议处理。
2. 每个TCP Socket有自己的send buffer和recv buffer:
- 接收数据时:TCP协议栈根据端口号,将收到的数据解复用到对应的Socket,并将载荷存入对应的recv Buffer。
- 发送数据时:TCP协议栈根据端口号,将发送数据存入对应Socket的send buffer,之后被TCP打包形成发送报文,并复用到IP进行发送。
[五] TCP发送窗口和接收窗口
关于TCP接收窗口和发送窗口的说明:
1. 关于发送窗口的说明:
- send window的大小:发送窗口的大小,由对端数据报携带的rwnd反馈和拥塞控制窗口cwnd综合决定:发送方窗口 = Min [ rwind, cwind ]。
- 发送窗口的滑动:当收到一个ACK,若携带的ACK位置之前的数据均已被确认,则窗口base滑动向此SEQ所指位置。也既发送窗口的base指向最后一个已发送但未确认的字节。
- 发送时,能发送多少字节,取决于两个因素:第一,本端发送窗口;第二,对端接收窗口余量。发送时,若因发送窗口满,或者因为对端接收窗口余量为零,应用层的待发送的数据将被缓存。
2. 关于接收窗口的说明:
- 接收窗口的大小:被应用所控制,应用可以通过SOCKET的setsockopt()调节接收窗口和接收buffer的初始大小。默认的初始值由TCP根据本端软硬件水平设置。
- 接收窗口的滑动:当收到一个数据包,若此包SEQ之前的数据均已收到,则接收窗口的base滑动向“SEQ + 报文大小”。也既接收窗口的base指向最后一个确认完毕字节的下一个字节。
- 当接收端接收窗口为零时,发端会定时发送一字节的wnd查询包,以便当接收端recv window有空闲字节可用时,发端可以及时知晓;
三 TCP的动态特性
[一] 面向连接
关于建立连接的说明:
Server端的SYN消息中携带了ACK。所以其实三次握手是:
- Client -> Server:SYN
- Server -> Client:ACK
- Server -> Client:SYN
- Client -> Server:ACK
其中2. 和3. 合并成了一条消息。
关于断开连接的说明:
1. TCP有两种断开连接的方式:FIN优雅断链;RST粗暴断链;
2. 通过FIN优雅的断链:Why三次握手,但是四次挥手?
TCP通过FIN断开链接过程物理意义如下:
- 主动端请求断开连接;
- 被动端同意;
- 被动端发送缓存的待发数据;
- 被动端断开连接;
- 主动端同意;
由此可见,如果四次挥手合并为三次挥手,被动端就失去了发送缓存数据的机会。总而言之,四次挥手是为了"优雅的"断开连接。
3. 通过RST粗暴的断链,步骤如下:
- 主动端直接用socket.close;
- 主动端清空所有缓存数据;
- 主动端发送RST复位消息并关闭连接;
- 被动端收到RST复位消息,直接清空所有缓存数据并关闭连接
[二] 确认机制
关于确认机制的说明:
TCP实践中,每个TCP数据包的ACK标识总是1,ACK Seq也总是携带着某个序列号。无论携带的序列号是不是已经被确认了百八十遍了。TCP永远不会浪费ACK Seq。
[三] 选择性重传:
关于选择性重传的说明:
- TCP协议提供可靠数据传输服务。为保证数据传输的正确性,TCP重传其认为已丢失的包。
- TCP根据接收端返回至发送端的一系列确认信息来判断是否出现丢包。当数据段或确认信息丢失,TCP启动重传操作来重传尚未确认的数据。
TCP拥有两套独立机制来完成重传:
其一,基于时间,也即超时重传;
其二,基于SACK,也即选择确认。当TCP发现”空缺”时,发起重传来填补空缺;
1. TCP并不对每个到来的数据包都返回ACK,利用TCP的累积ACK字段。累积确认可以允许TCP延迟一段时间发送ACK,以便将ACR和相同方向上需要传的数据结合发送。但是注意TCP不能任意时长地延迟ACK,避免对方会误认为数据丢失而进一步出现不必要的重传。
2. TCP超时重传时间:
超时重传无外乎通过一个定时器来为发送出去的数据包计时,当ACK接收超时时发起重传。关键是重传超时时间RTO,这个东东怎么计算?TCP有算法来测算此RTT时间。该时间取值的目标是保证对网络资源最小的浪费。
RTO测算算法有若干种,例如:
RFC793(TRANSMISSION CONTROL PROTOCOL)的算法;
RFC6298(Computing TCP's Retransmission Timer)的算法;(linux采用)
[四] 流量控制
关于流量控制的说明:
- 流量控制的目标:发端的发送buffer和接收端的接收buffer就发送速度协商一致,避免发送的太快而导致接收端buffer爆掉。
- 流量控制的方法概述:通过接收buffer反馈完成流量控制。发送端将本端的Socket接收Buffer的剩余空间信息放在TCP数据包的“接收窗口”字段中。接收端根据对方的”接收窗口”信息,决定接下来可以发送的数据量。
- 零窗口探测报文段: 为了避免收到零窗口报文后,因为丢包等原因无法获知对方已经有新窗口空间可用。当TCP连接的一方收到对方的零窗口通知时就启动持续计时器。若持续计时器设置的时间到期,就发送一个仅仅有一字节数据的零窗口探测报文段,而零探测报文的接收方则会给出新的窗口值。而且TCP规定,即使接收窗口已经满载,也必须接收以下几种报文段:零窗口探测报文段、确认报文段,携带紧急数据的报文段。
- 糊涂窗口综合征和Nagle算法
[五] 拥塞控制
关于拥塞控制的说明:
1. 什么是网络拥塞:网发送端到接收端的漫长路径中,如果中间有某个或者某几个路由器出现了缓存溢出现象,这种现象称为网络拥塞。当网络出现拥塞,所有途径拥塞点的数据包都面临丢包的危险。如果此时各个终端不仅不降速,而且因为丢包而且重传了更多的数据包进入网络,那么网络拥塞的程度只会恶化。为了避免这种状况,TCP提出了拥塞算法。
2. 拥塞控制总体思路:当拥塞状况出现或将要出现时,减缓TCP发送端的发送速率;若拥塞情况有所缓解,可以检测和使用新的可用带宽。RFC2581(TCP Congestion Control protocol)定义了拥塞控制的四个算法:
- 慢启动(Slow-start);
- 拥塞避免(Congestion Avoidance);
- 快重传(Fast Restrangsmit);
- 快恢复(Fast Recovery);