linux网络协议笔记
三握四挥
TCP
有连接、可靠传输与按序到达、流量控制、拥塞控制
有链接
- 三次握手
建立链接
client server
socket socket
bind
listen
connect accept
rw rw
close close
状态转换
client server
CLOSED CLOSED
LISTEN
SYN-SENT
ESTABLISH SYNT-RCV
ESTABLIS
- 四次挥手
A B
FIN-WAIT-1
CLOSE-WAIT
FIN-WAIT-2
LAST-ACK
TIME-WAIT
CLOSED
TIME-WAIT的目的:防止被动结束端关闭链路时,没收到主动端的ACK,继续重发FIN。如果此时主动端已经结束,并将端口分配给另一个链接,且这个重发的fin刚好落在新链接的期望序列号范围。
五元组标志一个链接,而不是socket标志一个链接,(src ip, src port, dst ip, dst port, proto)
可靠传输 & 按序达到
有序列号和ACK确认机制保证
- 发送端收到ack后,会认为ack前面的所有数据接收端都收到了
- 接收端会丢弃重复的消息(序列号重复),但ACK还是会重发
- 接收端在内存里保存一些乱序报文,通过选择确认机制告诉发送端哪些需要重发
重传机制有很多:超时重传、快重传、选择重传
参见
流量控制
基于滑动窗口
- 糊涂窗口综合征 : 接收端应用处理的慢,导致接收端窗口比较满,空出很小空间就通知发送端空了一个小空间了
利用率低,小于一定阈值是告诉发送端,接口窗口为0
- Nagle算法: 发送端频繁发送小报文
在发送端进行累积
- 延迟ACK : ack消息太多了
接收端ACK延迟到接收端发送数据给发送端时带回去,或者定时器触发
拥塞控制
基于拥塞窗口
TCP流量控制、拥塞控制
流量控制需注意死锁问题
慢启动(从1开始倍数增加cwnd),拥塞避免(cwnd>ssthresh时,cwnd每次加一);任何时候丢包,ssthresh变为当前cwnd的一半,cwnd置一,重新开始慢启动
快重传:当接收端收到一个失序报文,立即发送三个重复ack给发送端,发送端重发这个报文
快恢复:慢启动-拥塞避免算法中,丢掉报文时,ssthres = current cwnd size /2, cwnd=1,快恢复是收到三个重复ack时,ssthresh=current cwnd size /2, cwnd= ssthresh
异常理解
close, shutdown, rst,优雅关闭链接,timeout等
tcp中rst异常关闭问题
Graceful shutdown server socket
TCP链接的关闭
shutdown和close的区别
如果本端收到一个rst,继续读该socket,会受到ECONNRST错误,继续写,会收到EPIPE;
如果本端收到fin,继续读socket会返回0;继续写呢??可以继续写。
如果最后的rst丢失,因为发送rst端socket已经关闭,所以再往这条链路写,会遇到rst;读会永远阻塞住(我的理解),类似主机奔溃。