三次握手连接建立过程
Ack 发送者希望接受到的下一个序列号
1.客户端将syn设为1
初始化seq 这里relative是相对的sequence
2.服务端 将syn设为1并返回ack 也就是下一次的sequence number syn+ack 设置上服务器的sequence number
3.客户端确认 将syn设为0并 发送ack 并将sequence加1
这时握手已经完成可以直接发送数据包 通过序列号加长度确认数据 以后的next ack会是当前sequence+数据长度
四次挥手
1.fin设置为1表示连接已完成 发送seq序列号 还包含一个ack段用来确认对方最近发送的报文
2.服务端发送ack fin 因为有延迟确认的存在,把第二步的 ACK 经常会跟随第三步的 FIN 包一起捎带会对端。 刷新数据并发送 将序列值加1作为响应ack辨病接受到fin,发送自己的fin
3.客户端回复ack
半关闭 : 连接的一方关闭,另一方任在发送数据
连接超时
cat /proc/sys/net/ipv4/tcp_syn_retries 控制 默认为6 没超时间隔是前面间隔的两倍
tcp选项
最大段大小选项 只记录tcp数据字节数
选择确认选项 防止使用超出空洞的数据(数据无序) 当出现乱序数据时提供一个sack选项描述这些乱序的数据帮助对方重传,
Time_wait
2Msl 最大报文生存周期 能够让tcp重新发送最终的ack避免出现丢失的情况
只有当一条新连接使用的序列号超过连接前使用的序列号或一条新连接允许使用时间戳选项来区分之前的连接,这条连接才能被再次使用
可靠地终止连接
保证让迟来的tcp报文有足够的时间被识别并丢弃
可以通过SO_REUSEADDR 强制使用Time_wait端口
FIN_WAIT_2 状态
防止出现无限等待 设置计时器,如果计时器超时连接是空闲的,tcp连接就会转移到CLose状态
RST 复位报文段 通知对方重新建立连接 可以与关闭连接 不用等数据全部发送完毕 SO_LINGER(与fin相比)
端口未监听
发送端所有发送队列的数据将会被丢弃
处理半打开连接 返回rst (未通知对方直接关闭连接 可使用keepalive)
对于无状态的连接
Broken pipe`出现的时机是:在一个 RST 的套接字继续写数据,就会出现`Broken pipe
SYN 泛洪
使用syncookies 当syn当到达时,这条连接存储的大部分信息都会被编码并保存在syn+ack报文段的序列号字段,只有在syn+ack被确认后才会分配资源
tcp 11种状态
全连接队列和半连接队列与 backlog
当listen后,tcp的状态会由close变为listen状态
syn队列与accept队列 max_syn_backlog(系统变量控制) backlog(应用程序控制)
SO_LINGER
SO_LINGER 启用时,操作系统开启一个定时器,在定时器期间内发送数据,定时时间到直接 RST 连接。
Max Segment Lifetime 报文最大生存时间
Time_Wait 状态
主动发送fin的一端发送完后会进入time_wait状态并等待对方发送fin报文,防止新连接与老连接混用造成报文混淆,time_wait时间内被动fin方可以发送fin报文
RST
Connection Reset 如果返回rst说明端口没有对外监听,信息丢失无法处理返回rst,无法发送 断网 都会出现rst
重传机制
120s 15次
快速重传机制:当发送者收到3次以上重复的ack时,不用等待超时重传
滑动窗口
拥塞控制
通过接受窗口控制发送窗口,
慢启动: tcp连接建立好后悔初始化发送cwnd为1W相当于2-4个SMSS,
CWND += min(cwnd,smss
-
当 cwnd < ssthresh 时,拥塞窗口按指数级增长(慢启动)
-
当 cwnd > ssthresh 时,拥塞窗口按线性增长(拥塞避免)
-
慢启动:拥塞窗口一开始是一个很小的值,然后每 RTT 时间翻倍
-
拥塞避免:当拥塞窗口达到拥塞阈值(ssthresh)时,拥塞窗口从指数增长变为线性增长
-
快速重传:发送端接收到 3 个重复 ACK 时立即进行重传
-
快速恢复:当收到三次重复 ACK 时,进入快速恢复阶段,此时拥塞阈值降为之前的一半,然后进入线性增长阶段