TCP协议总结
MSS(maximum segment size)只能出现在SYN包中,通信双方在SYN包和SYN+ACK包中互相通告各自能接收的MSS
SYN包不能携带data,占用seq
ACK包能携带data,携带data时占用seq,不携带data时不占用seq
FIN包能携带data,不论是否携带data都占用seq
即使窗口为0,也必须接收零窗口探测包、ACK包、URG包
七个定时器
- 连接建立定时器(connection establish):发送syn包后启动,到期(75s)还没收到syn+ack包,终止连接
- 重传定时器(retransmit):发送包后启动,到期(2*RTT)还没收到ack包,重传
- 坚持定时器(persist):收到零窗口包后启动,到期还没收到包,发送零窗口探测包
- 为避免糊涂窗口综合症,不通告小窗口,防止小包降低带宽利用率
- 保活定时器(keeplive):每次收到包后启动,到期(2小时)还没收到包,发送保活探测包
- 保活探测包发送10次,每次等待75s,到期还没收到ack包,终止连接
- 时间等待定时器(TIME_WAIT):进入TIME_WAIT后启动,到期(2*MSL)还没收到FIN包,终止连接
- 结束等待2定时器(FIN_WAIT_2):进入FIN_WAIT_2后启动,到期(10m+75s)还没收到FIN包,终止连接
- 延迟确认定时器(delay ack):收到包后启动,到期(200ms)还没发送包,发送ack包
TCP首部
- URG:当URG=1时,紧急指针有效,seq + 紧急指针表示紧急数据最后一个字节的序号(紧急数据有紧急指针 + 1个字节)
- PSH:接收端收到PSH=1的包后不缓存,立即交给应用层
- RST:http://www.vants.org/?post=22
- 1、client发SYN包,但server没监听,返回RST包
- 2、client发非SYN包,但server连接不存在或连接即将关闭,返回RST包
- 3、server close fd(主动或被动关闭),向client发送RST或FIN包,发送RST或FIN包由SO_LINGER(延迟关闭)决定
- 4、client向server发包重传超过一定次数,向server发送RST包
- 5、client/server可以主动向对端发送RST包(短连接)
- 常用TCP选项:MSS选项、窗口扩大(Window Scale)选项、时间戳(Timestamp)选项、选择确认(SACK,Selective ACK)选项
发送/接收缓存和窗口
发送缓存和窗口的左边沿重合,接收缓存和窗口的右边沿重合
发送报文的seq和ack的计算公式
除了重传报文,发送报文一定是连续的,但是接收报文不一定是连续的,可能乱序
SYN和FIN包的data长度看作1,不携带data的ACK包的data长度看作0
- 发送报文的seq = 最近一个非重传发送报文的seq + data长度
- 发送报文的ack = 最近一个非重传连续接收报文的seq + data长度
方向 | 包类型 | SYN | ACK | FIN | seq | ack | data长度(字节数) |
---|---|---|---|---|---|---|---|
C->S | SYN | 1 | 0 | 0 | x | 无效 | 0 |
S->C | SYN+ACK | 1 | 1 | 0 | y | x+1 | 0 |
C->S | ACK | 0 | 1 | 0 | x+1 | y+1 | 0 |
C->S | data | 0 | 1 | 0 | x+1 | y+1 | m |
C->S | data | 0 | 1 | 0 | x+m+1 | y+1 | n |
S->C | ACK | 0 | 1 | 0 | y+1 | x+m+n+1 | 0 |
S->C | data | 0 | 1 | 0 | y+1 | x+m+n+1 | p |
C->S | ACK | 0 | 1 | 0 | x+m+n+1 | y+p+1 | 0 |
C->S | FIN | 0 | 1 | 1 | x+m+n+1 | y+p+1 | 0 |
S->C | ACK | 0 | 1 | 0 | y+p+1 | x+m+n+2 | 0 |
S->C | data | 0 | 1 | 0 | y+p+1 | x+m+n+2 | q |
C->S | ACK | 0 | 1 | 0 | x+m+n+2 | y+p+q+1 | 0 |
S->C | FIN | 0 | 1 | 1 | y+p+q+1 | x+m+n+2 | 0 |
C->S | ACK | 0 | 1 | 0 | x+m+n+2 | y+p+q+2 | 0 |