TCP/IP卷1
TCP相关章节18-22章
首部格式
16位源端口号,16位目标端口号
32位序号
32位确认序号
4位首部长度,6位保留,6位操作标志位(URG,ACK,PSH,RST,SYN,FIN),16位窗口大小
16位校验和,16位紧急指针
PSH PUSH 尽快把数据发给接收进程
RST RESET 复位连接
FIN FINISH 发送方完成数据发送
SYN synchronous 同步
URG urgent 紧急
建立TCP连接/三次握手
- 请求段(通常为客户)发送一个SYN指名客户打算连接的服务器的端口,以及初始序号ISN。这个SYN段为报文段1
- 服务器发回包含服务器初始序号的SYN报文段(报文段2)作为应答。同时,将确认序号设置为客户的ISN加1以对客户的SYN报文段进行确认。一个SYN将占用一个序号
- 客户将确认序号设置为服务器的ISN加1以对服务器的SYN报文进行确认(报文段3)
四次握手是由TCP协议的全双工和半关闭造成的
Maximum Segment Size 最大报文长度
TCP的MSS默认为536
MSS越长,相比于20字节的TCP首部和20字节的IP首部来说都更长
TCP状态变迁
典型状态变迁:
建立连接:
SYN_SENT LISTEN
SYN j
SYN_RCVD
SYN k,ACK j+1
ESTABLISHED
ACK k+1
ESTABLISHED
断开连接:
FIN_WAIT_1
FIN m
CLOSE_WAIT
ACK m+1
FIN_WAIT_2
LAST_ACK
FIN n
TIME_WAIT
ACK n+1
CLOSED
如果从LISTEN状态,收到SYN,然后发SYN,ACK进入SYN_RCVD,再收到RST就会回到LISTEN
TIME_WAIT要等待2MSL maximum segment life 去向ACK消息最大存活时间(MSL) + 来向FIN消息的最大存活时间(MSL)
同时打开/同时关闭
机器1用8888向机器2的7777端口发送SYN,机器2用7777向机器1的8888发送SYN
则两个机器收到SYN之后发送SYN,ACK,同时进入SYN_RCVD
接受到SYN,ACK进入ESTABLISHED
同时关闭也是一样
从FIN_WAIT_1 -> CLOSING -> TIME_WAIT
滑动窗口
发送被确认 发送未被确认 可用的窗口 不能够发送
窗口由接收方通告
窗口左边沿向右边沿靠近叫窗口合拢,发生在数据被发送和确认时
窗口右边沿向右移动允许发送更多数据,我们称之为窗口张开,发生在接收端读取已经确认的数据并且释放了TCP的接收缓存时
- 发送方不必发送一个窗口大的数据
- 来自接收方的报文确认数据把窗口向右划动
- 窗口的大小可以缩小但是右边沿不能向左移动
- 接收方在发送一个ACK前不必等待窗口被填满,收到几个报文就可以发送ACK
窗口大小
接收方控制滑动窗口大小,这将影响TCP的性能
慢启动
拥塞窗口 cwmd congestion window
发送方开始发送一个报文段,收到ACK之后变为两个,收到这两个报文段的ACK之后,拥塞窗口变为4
从发送方发送报文段到发送方接受到ACK的时间为往返时间RTT round trip time
通常ack只有一个ip首部和一个TCP首部
连接的理想状态就是:
- 在一个时间段,每当接收方从网络上移去一个报文段,发送方就在发送一个报文段到网络上
- 不管有多少报文段填充了这个管道,返回路径上总是有相同数量的ACK
带宽的时延乘积
带宽时延乘积:bandwith * RTT = capacity 管道容量
拥塞
当数据从一个带宽大的管道向一个带宽小的管道传输时可能会发生数据丢失的情况
数据量太大路由器缓存无法存放也可能发生数据丢失的情况,这两种情况称为拥塞
ACK的时间间隔与带宽最小的管道一致
如果带宽小的瓶颈管道不能容纳拥塞的数据分组的缓存,就会发生拥塞
超时重传
超时重传中最重要的就是对于给定连接的RTT的测量
由于路由器和网络流量随时会变化所以我们假设RTT也会随时变化
R <- aR + (1-a)M
a是一个推荐值为0.9的平滑因子,每次进行新的测量的时候,这个平滑的RTT将得到更新,90%来自于上一个RTT,10%来自于新的测量
Retransmission time-Out,RTO 重传超时时间
RTO测量公式:
Err = M - A
A <- A + gErr
D <- D + H(|Err| - D)
RTO = A + 4D
A为加权平均往返时间RTTs D为偏差的加权平均值RTTv
拥塞避免算法
假定由于分组收到损坏引起的丢失是非常少的,因此分组丢失就意味着在源主机和目的主机之间的某处网络上发生了阻塞
拥塞避免算法和慢启动算法需要维持两个变量:一个拥塞窗口cwmd和一个慢启动门槛ssthresh
对一个给定的连接,初始化cwmd为一个报文段,ssthresh为65536个字节
TCP输出不能超过cwmd和接收方通告窗口的大小,拥塞避免是发送方使用的流量控制,通告窗口是接收方使用的流量控制,前者是发送方感受到的网络拥塞的估计,后者与接收方在该链接上可用的缓存大小有关
拥塞发生时(超时或者收到重复确认),ssthresh被设置为当前窗口的一半大小(当前窗口是cwmd和接收方通告窗口的最小值,最小为两个报文段。此外,如果是超时导致了拥塞,cwmd被设置为1个报文段,这就是慢启动
当新的数据被对方确认时,就增加cwmd,增加的方法取决于我们现在正在慢启动或者是拥塞避免。如果cwmd小于ssthresh,则是进行慢启动,否则是拥塞避免
快速避免和快速恢复
收到三个重复的ACK时,将ssthresh设置为当前拥塞窗口cwmd的一半,重传丢失的报文段,设置cwmd为三倍的报文段大小
每次收到一个ACK时,cwmd增加一个报文段大小并增加一个分组(如果新的cwmd允许发送)
当下一个确认的ACK到达时,设置cwmd为ssthresh,这个ACK应该是在进行重传后一个往返时间对步骤1重传的确认。另外,这个ACK也是对丢失的分组和收到的第一个重复的ACK之间的所有报文段的确认。这一步采用的是拥塞避免,因为分组丢失时我们将当前的速率减半