核心机制一:确认应答 => 实现可靠传输的核心
接受方给发送方返回"应答报文"(ack)
1)发送方能够感知到对方是否收到
2)如果对方没有收到,发送方采取措施
序号按照字节编排 (连续递增)
确认序号按照收到数据的最后一个字节序号 + 1
核心机制二:超时重传 => 产生丢包之后,重传数据
可能是数据丢了,也有可能是 ack 丢了
接受方按照序号对数据重传(超时时间)
核心机制三:连接管理
有连接
连接:虚拟的,抽象的连接
通信双方各自保存对方的关键信息(IP,端口)
连接如何建立的(三次握手)
连接如何断开的(四次挥手)
连接如何建立的 (三次握手)
handshake 计算机术语
客套,打招呼,没有实质性的信息,通过打招呼换取对方的注意
TCP 中的握手,传输一个"打招呼"的数据包,这个数据包不携带任何"业务数据"(没有应用层的载荷),TCP 这个数据包自有报头,没有正文,也就是这个操作是不携带任何业务数据的
三次握手,建立连接的过程中,客户端和服务器要经过三次这样的"打招呼",连接才能在双方这边都建立好
synchronized 同步
在计算机中,通过一个术语,可能有多种用途需要结合上下文来理解含义
在多线程中表达的是"互斥"(只能有一个)
在咱们这个TCP 这个地方,表达的是"通知"这样的效果
1)客户端给服务器发起一个 syn(同步报文段)
客户端告诉服务器:我要和你建立连接,请你保存我的信息
2)服务器给客户端返回一个 ack
服务器告诉客户端:收到,我会保存的
3)服务器给客户端发起一个 syn
服务器也告诉客户端:我也要和你建立连续,请你保存我的信息
4)客户端收到之后,也返回一个 ack
客户端告诉服务器:收到,我会保存的
说好的三次呢
从流程/逻辑上是交互了四次,但是中间的两次,可以合并成一个 TCP 数据包,从网络上实际只传输了 三个数据包
返回 ack 和 发送 syn 都是内核控制的和应用程序代码无关(程序员干预不了),操作系统就可以在同一时间完成这俩的数据传输
三次握手的意义是什么? 解决了什么问题??
三次握手,也可以视为是一种"保证可靠传输的手段"(辅助手段)
1.三次握手,相当于是"投石问路",验证通信链路是否畅通
地铁 早上 6 点开始运营,0点就休息了,经过这个一晚上,地铁路线中是否会出现一系列的故障和异常?
地体第一班一般都会先空车跑一趟
2.三次握手,也是在验证通信双发的发送能力和接受能力是否是正常的
3.通过三次握手,让通信双方协商关键信息(和可靠性不是很相关,但是也有用)
TCP 建立连接的过程中,有一个数据是需要进行协商的,就是 TCP 的起始序号
TCP 的序号,针对载荷部分按照字节编号.
当 TCP 建立好了之后,传输的第一个数据包的第一个字节的编号,不是从 1 / 0 开始编排的
而是在三次握手阶段协商出来这样的数字,作为起始编号
编号不从 0 开始有啥用?
每次建立连接,协商出来的起始编号都是不同的(差别很大)
这样的设定的目的,为了避免出现网络传输中的特殊情况
"用前朝的剑,斩本朝的官"
在数据进行多次交换传输的时候,可能会出现 其中的某个数据"迷路了"因为网络的一些延迟导致绕了很长的路经过了很长的时间才到达服务器
当这个数据包到达服务器的时候,此时连接已经变了,已经是其他的连接
此时这个数据包该如何处理呢?
1.服务器正常处理
2.丢弃(正确做法)
三次握手的意义
1.验证通信链路是否畅通
2.验证通信双方的发送能力和接受能力
3.协商关键的信息
TCP 建立过程中涉及到的,操作系统的 原生 API (Linux 系统中提供的 C 语言风格的 api)
在 Java 里面对上面的 api 进行了大幅度的简化
咱们只需要知道,客户端 new Socket 对象触发 三次握手
服务器这边通过 accept 把已经建立好的连接拿到应用程序中(accept 接触阻塞的时候,三次握手已经完成了)
LISTEN :服务器存在的状态
服务器 new ServerSocket 就会进入到 LISTEN 表示在"监听"这个端口,端口上过来的客户端,就能 accept 了(手机开机,状态良好)
ESTABUSHED:客户端和服务端连接建立好了
客户端和服务器之间就可以进行通信了(电话已经接通,可以说话了)