文章 https://zhuanlan.zhihu.com/p/472361432 的学习笔记
TCP是面向连接的、可靠的、基于字节流的传输层通信协议
面向连接:只能一对一,不能一对多
TCP的连接是通过四元组唯一确认的:源IP、目标IP、源端口、目标端口
TCP和UDP的区别
TCP | UDP | |
---|---|---|
1 | 可靠 | 不可靠(丢包、乱序) |
2 | 需要建立连接 | 不需要连接,即刻传输数据 |
3 | 一对一 | 一对多 |
4.有无拥塞控制和流量控制 | 有 | 无 |
5.头部长度开销 | 20字节(若有“选项“字段则会更长) | 8字节 |
6.传输方式 | 流式传输 | 分包发送 |
TCP的目的是在不可靠的信道上建立可靠的连接
三次握手
.
.
.
.
.
注意,只有第三次握手可以携带应用层数据
为什么是三次握手而不是两次握手?
- 避免旧连接初始化造成混乱(主要原因)
.
网络拥堵时,旧连接可能未抵达,第三次握手用于确认是否是旧连接,如果是则发送RST报文,而两次握手做不到
- 三次握手确认了C/S双方都能同步序列号(Ack=Seq+1),而两次握手只能确认服务器同步无误
序列号能够保证数据不重复,不丢弃,按序传输
- 如果是两次握手,服务器收到SYN后只能直接分配资源建立连接,如果多个SYN阻塞在网络中,服务器会创建多个无效连接,造成资源浪费
四次挥手
连接断开后,服务器的资源得到释放
.
第一次挥手:我没有话要说了,但我还能继续听你说
第二次挥手:好的我知道了,我还有一些要说的话
第三次挥手:我现在也没有话要说了
第四次挥手:好的
为什么是四次挥手而不是三次挥手?
因为FIN+ACK是分开的,而握手的时候SYN+ACK是合在一起的
为什么要TIME_WAIT并且是2MSL?
MSL(Maximum Segment Lifetime,报文最大生存时间),Linux默认为30s,对应于IP中的TTL字段
设置TIME_WAIT是为了保证最后的ACK能够到达服务器,使其正常关闭
因为如果ACK没有到达服务器,服务器会超时重传FIN,而如果客户端此时关闭,服务器会一直处于LAST_ACK状态
经过2MSL的时间,足够让两个方向的旧数据包都被丢弃,使得信道内的数据包都是新连接产生的