TCP 面向字节流,所以应用程序直接给过去的一段内容可能会被拆分为多个字节流,或者合并
TCP 只支持 1 对 1 模型,单播。UDP 支持单播,多播,广播。
TCP 头部至少是 20 字节,至多 60 字节。UDP 则固定为 8 字节
HTTP/3.0 之前是基于 TCP 协议的,而 HTTP/3.0 将弃用 TCP,改用基于 UDP 的 QUIC 协议(目前 3.0 就是最新的,它和 html5 是两个东西)
注:FTP 是和 HTTP 一样,也有对应的 SFTP、FTPS
三次握手
1、
首先,服务器是一直跑的,客户端选择一个时机访问服务器。并且只能是客户端访问先访问服务器
所以,第一次是客户端 -> 服务器 : SYN 报文
Synchronize Sequence Numbers :同步序列号
其中包含一个随机的初始序列号 Initial Sequence Number, ISN
这里一般写为 seq=x
然后 客户端发送好了,就可以等着了,其进入** SYN_SEND**
2、
服务器收到以后,同意建立连接
其发送一个确认报文,包含 SYN+ACK
其中:
SYN 和第一次一样,是服务器自己的同步序列号,写为 seq=y
ACK 用于告诉客户端我已经收到了,就给客户端的 x+1,即 ack=x+1
发送后,服务器可以等着,进入** SYN_RECV**
3、
客户端收到以后
发送一个 ack=y+1,确认一下,然后客户端进入 ESTABLISHED
服务器收到以后,也进入 ESTABLISHED
这三次发送,是要确定双方,都既可以接收,又可以发送
是双方要站在自己的视角确认这个事情,你自己确认后,对方其实不知道
第一次握手 (客户端 → 服务器) :客户端发送 SYN 包。
- 客户端:自己能发。
- 服务器:客户能发,自己能收。
第二次握手 (服务器 → 客户端) :服务器回复 SYN+ACK 包。
- 客户端:自己能收能发,服务器能收能发
- 服务端:客户能发,自己能收+发(这里是关键:为什么需要第三次,因为服务器不知道客户端能不能收到)
第三次握手 (客户端 → 服务器) :客户端发送 ACK 包。
- 客户端:客户端在收到服务器回复以后,自己的视角就确定双方是都是好使的,只是服务端视角不知道自己(自己指服务器视角下的客户端)能不能收到
- 服务端:收到 ACK 以后,确认客户能收即可
第三次握手,不仅能告诉服务器,我能收到,而且还可以拒绝服务器。比如第一次握手发慢了,又不想连接了,可以拒绝
四次挥手
当不想再服务时,任何一方都可以率先提出终止服务,所以是对称的。这里假设是客户端先提出
1、FIN
客户端 -> 服务器 FIN
FIN = finish = 终止,包含 seq=u
客户端进入,FIN-WAIT-1
2、ACK
服务器收到以后,回复可以,但是稍等
ACK ,包含 seq=u+1
服务器进入 CLOSE-WAIT 状态,等待关闭
客户端收到以后,进入 FIN-WAIT-2
此时 TCP 处于半关闭状态,客户端到服务端的发送通道已关闭,但服务端到客户端的发送通道仍然可以传输数据
3、FIN
服务器把所有的数据都发送完以后,说可以彻底关闭了
FIN 包含 seq=y
服务器进入 LAST-ACK,等着最后回复即可
4、ACK
客户端收到 FIN 后,回复 ACK 包含 seq=y+1
客户端进入就 TIME-WAIT
服务器收到以后,进入 CLOSE
客户端等一会,等 2MSL 之后,直接 CLOSE
(关键:为什么要等一会,现在确实已经确定要关机了,但是客户端不确定自己发的 ACK 服务器能不能收到,如果服务器收到,服务器关机,则自己不会收到消息,即确定电话里没有声音了,再关机,否则服务器没收到 ACK,会重复发 FIN)
TCP 提供可靠的数据传输服务,但这并不意味着在连接关闭过程中不会出现报文丢失。可靠传输是通过确认、重传等机制实现的,但在连接关闭阶段,同样需要这些机制来保证关闭的可靠性。
至于开始时也有可能丢包,确实,但是那样就直接无法建立就完了,不是更好吗?
当说 TCP 是"可靠"的,意思是应用层最终能得到完整、有序的数据,而不是说每个报文都不会丢失。
这里关键点就是:
服务器不能直接和客户端说,直接关了吧
他们怕网络延迟,所以怕服务器还再说,但是 A 没收到呢
服务器必须先安慰客户端,然后等自己真说完了,才结束
流量控制
1、TCP 想的很美好,那就是让接收方告诉发送方,我现在的能力是多少,发送方动态调整
(服务器和客户端都可以即作为发送方也可以是接收方,双向嘛)
2、TCP 有确认机制,你收到了,你必须发送”收到“,所以,就把你的现在的能力写在 确认报文中的窗口字段
在发送方的视角里:
1、已经收到对方确认的
2、发送了但是还没有确认
3、我还没发送的
(3 这里他们有的分为两种,一种是在窗口内,一种是窗口外)
窗口内的即将发送,窗口外无法发送
窗口大小有接收者告诉我,然后我把 发送了但是还没有确认 + 窗口内的即将发送,设置为窗口大小
拥塞控制
1、这个是所有主机所有路由器一起做的事情
2、
慢开始 cwnd 初始值为 1,每经过一个传播轮次,cwnd 加倍
拥塞避免让拥塞窗口 cwnd 缓慢增大,即每经过一个往返时间 RTT 就把发送方的 cwnd 加 1.
快重传 快恢复