此笔记暂未作整理,留作后续回顾之用。
TCP协议学习笔记
1. TCP提供一种面向连接的、可靠的字节流服务。
1)面向连接
表示TCP在传送数据之前需要建立连接,在数据传送完后需要释放连接。
不过TCP的这种连接是逻辑上的端到端连接,并不是电路上的端到端连接。
2)可靠的
TCP的可靠性由报文确认、超时重传、乱序重组、重复丢弃以及流量控制等多种技术保证。
3)字节流服务
TCP对所传送的数据(字节流)不做任何解释,它只负责将数据从一端严格保证按序的搬运
到另一端,不包含应用层的数据边界,可以认为是从源到目的的条自来水管道,里面承载
的是连续的数据流,应用层需要自己负责数据重组。
2. TCP首部
|----------------|----------------|----------------|----------------|
| src_port | dst_port |
|----------------|----------------|----------------|----------------|
| seq_num |
|----------------|----------------|----------------|----------------|
| ack_num |
|----------------|----------------|----------------|----------------|
| hdr_len | rsv | flag | win_size |
|----------------|----------------|----------------|----------------|
| CRC | ugr_ptr |
|----------------|----------------|----------------|----------------|
| opt... |
|----------------|----------------|----------------|----------------|
src_port/dst_port:用来标识通信的进程,当然需要结合IP层信息。
seq_num:标识报文中的第一个数据字节的序号。
ack_num:发送端期望收到数据的下一个序列号,也就是上次已已经收到的字节数+1
ack_num = seq_num + size + 1
hdr_len:首部包含的32bit数目。不包含选项的话,正常情况为20字节,也就是5。
flag:|UGR|ACK|PSH|RST|SYN|FIN|
win_size:流量控制。
CRC:包含TCP头部和TCP数据的校验,这个与UDP是一样的。不过不一样的是,UDP的
校验和是可选的,而TCP的校验和是必选的。
ugr_ptr:发送紧急数据使用,只有当ugr标志位为1时才有效。
《TCP协议详解》中有这样一段描述:TCP可以表述为一个没有选择确认或否认的滑动
窗口协议。不过,发现TCP选项里面有sack选项,支持选择确认。
3. TCP连接的建立和终止
1) TCP通过三次握手建立连接。
2) TCP连接的终止可以使用三次或者四次握手,如果接收FIN端本身也要关闭连接,则可以
将FIN与ACK放到一个报文中发送过去,这样就节省一个报文,只需要3个报文。
4. MSS选项
MSS: Maximum Segment Size
1) MSS表示TCP传往另一端的最大数据块长度。
2) MSS有时候是可协商的,只能在SYN报文中携带,当一方不接受另一方的MSS时,就使用默认值536。
536 + 20 + 20 = 576,正好是X.25链路的MTU。事实上,MSS与底层链路的MTU相关。
3) 一般来说,如果没有分段发生,MSS越大越好,传输效率更高。
4) MSS是否会导致分片,理论上是由路径MTU决定的,不仅仅与两端链路MTU相关。
5. 2MSL等待
MSL:Maximum Segment Lifetime
1) MSL是任何报文被丢弃前在网络内的最长时间。RFC793指出MSL为2分钟,不过不同
系统采用的值并不一样。
2) 只有主动关闭才会有2MSL等待时间,发起主动关闭的一端会进入TIME_WAIT状态。
3) 2MSL存在的目的是主动关闭端发送ACK报文后,需要等待一段时间以处理ACK丢弃情况。
4) TIME_WAIT端口是指发起主动关闭一端进入TIME_WAIT状态的端口,可是通过设置
SO_REUSEADDR来重用处于TIME_WAIT状态的端口。
5) 处于TIME_WAIT状态的socket对理论上是不能够被重用的,不过有些系统通过某些
技术也可以实现复用。不过,这貌似不符合TCP协议规范。
6) 端口复用要解决的核心问题是:老连接的迟到报文不能够影响新连接的运行。
7) 有可能出现FIN_WAIT_2 <-> CLOSE_WAIT状态的无限等待。
6. RST报文
1) 通过RST报文释放连接称为“Abortive Release”,通过FIN报文释放连接称为“Orderly Release”。
2) RST报文不会导致任何响应。
3) 使用RST的典型情况有
a) 到不存在端口的连接请求。这个自己测试的结果是产生ICMP主机不可达信息,与书上描述不一样。
b) 通过设置选项SO_LINGER异常关闭一个连接。
c) 检测Half-Open连接。
7. 同时打开和同时关闭
1) 同时打开和同时关闭时在比较特殊的情况下才会发生的,严格的时序关系时。
2) 同时打开需要四个报文,比正常三次握手多一个报文;同时关闭也是四个报文,与正常关闭相同。
8. 延迟确认
1) 延迟确认是为了减少微小报文的发送,提高TCP的传输效率。
2) 延迟确认是通过一个定时器来实现的,在收到数据报文后,不会立即发送ACK,会先等待一段时间,
看是否有数据要发送,如果在定时器超时之前有数据要发送,则ACK与数据一起发送;否则,就等
到定时器超时在发送ACK。
3) 延迟确认发生在收到第一个未确认的报文时,立即启动延迟确认定时器。
4) 延迟确认在定时器超时之前如果一直没有数据报文,可能会积压多个ACK报文。
9. Nagle算法
1) Nagle算法的意义是能够有效缓解广域网的拥塞。
2) Nagle算法表述为:任意时刻,一个TCP连接上最多只能有一个未被确认的未完成的分组,在该分组
确认到达之前不能发送其他分组。
3) Nagle算法的优点是:
1) 在等待确认的时间内,TCP会收集少量分组,并在确认到来时以一个分组的方式发送出去。
2) 具有自适应性,确认到达的越快,数据也会发送的越快。
4) Nagle算法的副作用就是会产生时延,不太适合对网络实时交互有要求的应用。
5) 可以通过设置TCP_NODELAY选项来关闭Nagle算法。
10. 滑动窗口
1) 数据窗口指的是数据接收端的窗口,是数据接收端进行流量控制的手段。
2) 滑动窗口协议是TCP数据发送和接收方共同遵守的协议。
3) 理论上,接收端的数据窗口大小在三次握手时已经确定,但是在数据传输过程中,各种原因可能导致
接收端窗口中有未处理的缓存数据,此时,窗口大小就会变小了,表现为接收端的窗口大小会变化。
4) 滑动窗口指的是接收端通告的窗口,不是指协商参数中的固定窗口大小。
5) 数据窗口大小可以进行设置。数据表明,较大的数据窗口大小能够提高网络吞吐量。
11. PUSH标志
1) 发送方使用PUSH标志通知接收方将所有收到的数据全部提交给应用程序,包括与PUSH一起传送的数据
以及之前已经收到的数据。
2) 当前BSD SOCKET是否支持设置PUSH标志不知道,TCP能够自行决定什么时候需要置PUSH标志。
12. 慢启动
1) 慢启动是为了解决网络拥塞问题。
2) 如果一开就快速将接收端的窗口发满,被证明这种方式是如何严重降低TCP连接的吞吐量。
3) 慢启动在发送方使用一个拥塞窗口,初始化为1个报文段,每收到一个ACK报文就增加拥塞窗口大小,
直到发送速率和确认速率相匹配。
4) 发送方发送数据时取拥塞窗口和通告窗口的最小值作为发送上限。
13. 超时与重传
1) 超时和重传的策略的核心是如何确定超时间隔和如何确定重传频率。
2) RTT测量。
3) RTO(Retransmission TimeOut)计算。
4) 拥塞避免算法和慢启动算法是两个不同的、独立的算法,但是两者通常在一起实现。
5) 如果连续收到3个重复的ACK,就重传丢失的报文,无需等待超时器超时,这就是快速重传。
6) 如果快速重传后接下来立即执行拥塞避免算法而不是慢启动算法,这就是快速恢复。