传输层
2023-04-25 19:03:55 7 举报
AI智能生成
传输层
作者其他创作
大纲/内容
传输层服务
socket
概念:对网络中不同主机上的应用进程之间进行通信的接口
socket 地址
ip 地址
客户端或者服务端的网络 ip 地址
端口号
服务器运行很多个程序,需要通过端口号找到对应的应用程序
协议
socket 地址的协议类型只有两种
TCP
UDP
UDP协议
特点
发送数据的时机容易把控
立即发送
无需建立连接
无连接状态
无需在端系统中维护连接状态
分组首部开销小
首部数据小
UDP报文结构(报头8字节)
源端口(16bit)
目的端口(16bit)
UDP数据包长度(16bit)
实际对UDP数据包大小限制为512字节或8192字节,因为数据包越大,丢包率越高
校验和(16bit)
作用:检验数据在传输过程中是否被损坏
发送方UDP对报文端中所有 16 比特字符的反码进行求和
遇到溢出进行回卷(把前面多的1加到后面)
接收方进行同样计算,检测是否相同,可以检测绝大部分错误
TCP协议
面向连接
三次握手
握手前
客户端和服务端都是处于连接关闭状态
服务器调用socket()后使用bind()方法绑定IP和Port
服务端进入listen状态监听端口,等待客户端连接
客户端调用socket()使用connect()函数发起连接
1.第一次握手
客户端向服务端发送一个SYN(synchronize)包
标志位:SYN,表示请求建立连接
序列号为 Seq = x(x 一般为随机数)
客户端进入SYN-SENT 阶段
等待响应,若不能连接进入CLOSED状态
2.第二次握手
服务端收到SYN包
对该包进行确认
结束 LISTEN 阶段并返回一段 TCP 报文
标志位为 SYN 和 ACK:表示能正常接收客户端发送的数据,并同意创建新连接
序号为 Seq = y,将自己的初始序列号同步给客户端
确认号为 Ack = x + 1,告诉客户端自己接收的Seq没错
进入 SYN-RECV(同步接收) 阶段
当客户端和服务端同时发送请求进入SYN-SENT,客户端会转为SYN-RECV
3.第三次握手
客户端收到SYN + ACK 包
结束SYN-SENT,返回最后一段报文
标志位为 ACK:确认收到服务器端同意连接的信号
序号为 Seq = x + 1:收到服务器端的确认号 Ack,并将其值作为自己的序号值
确认号为 Ack= y + 1:表示收到服务器端序号 seq,并将其值加 1 作为自己的确认号 Ack 的值。
进入ESTABLISHED状态
一个数据传输状态,等待数据传输
握手后
服务端结束SYN-RECV 阶段,进入 ESTABLISHED 阶段,三次握手结束
为什么要三次握手
第一次握手:确认客户端可以正常发送数据
第二次握手:确认客户端可以正常发送数据,确认服务端可以正常接收数据。
第三次握手:确认客户端可以正常发送数据,确认服务端可以正常接收数据,确认服务端可以正常发送数据,服务可以正常接收数据。
握手失败
第一次握手丢失
客户端
客户端进入SYNC-SENT状态,等待第三次握手。
一段时间内无法收到第二次握手,触发超时重传机制,重新发送SYN报文
一般为1秒或3秒
收到握手,继续
未收到握手,继续重传,发送5次(内核参数控制)后,停止发送
服务端
一直处于listen状态
第二次握手丢失
客户端
同上,采用超时重传机制
服务端
进入SYN_RCVD 状态等待报文
一段时间内无法收到第二次握手,触发超时重传机制
未收到握手,继续重传,发送5次(内核参数控制)后,停止发送
第三次握手失败
客户端
处于 ESTABLISHED 状态,直到再次收到第二次握手进行重传,ACK没有超时重传机制
服务端
触发超时重传机制,直到连接成功或者达到最大重传次数
四次挥手
挥手前
客户端和服务端都处于连接状态(ESTABLISHED)
客户端调用close函数,关闭其套接字
服务器recv()函数处理close请求,进入四次挥手
第一次挥手
客户端向服务器发送一段 TCP 报文表明其想要释放 TCP 连接
标记位为 FIN,表示请求释放连接
序号为 Seq = u
客户端进入 FIN-WAIT-1 阶段,即半关闭阶段
客户端停止向服务端发送通信数据
第二次挥手
服务器接收到客户端请求断开连接的 FIN 报文
结束 ESTABLISHED 阶段,进入 CLOSE-WAIT 阶段并返回一段 TCP 报文
标记位为 ACK,表示接收到客户端释放连接的请求
序号为 Seq = v
确认号为 Ack = u + 1,表示是在收到客户端报文的基础上,将其序号值加 1 作为本段报文确认号 Ack 的值。
服务器开始准备释放服务器端到客户端方向上的连接
客户端收到服务器发送过来的 TCP 报文
客户端结束 FIN-WAIT-1 阶段,进入 FIN-WAIT-2 阶段
第三次挥手
服务器端会将遗留的待传数据传送给客户端
待传输完成后再次向客户端发出一段 TCP 报文
标记位为 FIN 和 ACK,表示已经准备好释放连接了
序号为 Seq = w
确认号 Ack = u + 1表示是在收到客户端报文的基础上,将其序号 Seq 的值加 1 作为本段报文确认号 Ack 的值。
随后服务器端结束 CLOSE-WAIT 阶段,进入 LAST-ACK 阶段
停止向客户端发送数据
第四次挥手
客户端收到从服务器发来的 TCP 报文
客户端结束 FIN-WAIT-2 阶段,进入 TIME-WAIT 阶段
客户端向服务器发送一段报文
标记位为 ACK表示接收到服务器准备好释放连接的信号;
序号为 Seq= u + 1,表示是在已收到服务器报文的基础上,将其确认号 Ack 值作为本段序号的值;
确认号为 Ack= w + 1,表示是在收到了服务器报文的基础上,将其序号 Seq 的值作为本段报文确认号的值。
挥手后
客户端开始在 TIME-WAIT 阶段等待 2 MSL
服务器端收到从客户端发出的 TCP 报文
服务器结束 LAST-ACK 阶段,进入 CLOSED 阶段。
客户端等待完 2 MSL 之后,结束 TIME-WAIT 阶段,进入 CLOSED 阶段
为什么要四次挥手
确认双方都得知双方都没有要传输的数据。
第一次挥手:客户端向服务端请求关闭连接。
第二次挥手:服务端收到客户端的请求,并且告知客户端等我处理完毕数据。
第三次挥手:服务端处理完毕数据,告知客户端,服务端数据处理完毕。
第四次挥手:客户端得知服务端数据处理完毕,双方数据都处理完毕,可断开连接。
挥手失败
第一次挥手失败
客户端
触发超时重传机制,达到上限直接关闭连接
服务端
无感知,一直处于ESTABLISHEN状态
第二次挥手失败
客户端
同第一次
服务端
无感知,一直处于CLOSE-WAIT,收到第一次挥手请求后重发第二次挥手报文
第三次挥手失败
客户端
处于 FIN-WAIT2 状态一段时间(30s或者60s,根据系统参数)后,关闭连接。
服务端
处于LAST-ACK一段时间(30或者60s,根据系统参数),重发第三次挥手,时间过了,断开连接
第四次挥手失败
客户端
收到重发的第三次握手,再次发送第四次挥手,等待2MSL时间,无更多报文断开连接
服务端
处于LAST-ACK一段时间(30或者60s,根据系统参数),重发第三次挥手,时间过了,断开连接
四次挥手的问题
客户端和服务端在较长时间内处于半连接状态
浪费大量连接资源
可以修改内核参数,减少等待时间
TCP报文结构(报头20字节)
源端口(16bit)
目的端口(16bit)
序列号(32bit)Seq
确认号(32bit)ACK
标志位(16bit)
前4位:TCP头长度
中6位:保留
后6位:控制位
URG 表示紧急指针标志
1有效0忽略
ACK 为确认序号标志
即相应报文段包括一个对已被成功接收报文段的确认
PSH 为 push 标志
该位为 1 时,则指示接收方在接收到该报文段以后,应尽快将这个报文段交给应用程序而不是在缓冲区排队
RST 为重置连接标志
出现错误连接时,使用此标志来拒绝非法的请求
SYN 为同步序号
连接的建立过程中使用
FIN 为 finish 标志
用于释放连接
接收窗口(16bit)
用于 TCP 流量控制
告诉发送方其窗口大小,控制发送速率
校验和(16bit)
奇偶校验
检验数据是否发生改动,检测出差错,丢弃该 TCP 报文
紧急数据指针(16bit)
告知紧急数据所在的位置
URG标志位为 1 时才有效
紧急数据存在时,TCP 必须通知接收方的上层实体对紧急模式采取相应的处理
选项
该字段一般为空,主要作用:
TCP 连接初始化时,通信双方确认最大报文长度
在高速数据传输时,可使用该选项协商窗口扩大因子。
作为时间戳时,提供一个 较为精准的 RTT。
数据
三次握手四次挥手数据部分为空
子主题
如何保证可靠传输
数据分块
应用数据被分割成 TCP 认为最适合发送的数据块
每一个数据块进行编号
每次接收方收到数据后,都会对传输方进行确认应答
出现数据块丢失或者发送重复,删除重复的数据块,要求发送方重新发送丢失的数据块
校验和
监测数据传输过程中可能出现的差错
流量控制
发送方发送的数据量不能超过接收端窗口剩余大小
接收方来不及处理发送方的数据,会提示发送方降低发送的速率,防止丢包
TCP 通过滑动窗口协议来支持流量控制机制
ARQ自动重传协议
每发完一个分组就停止发送,等待对方确认。在收到确认后再发下一个分组。
超时重传
当 TCP 发出一个报文段后,启动一个定时器
等待目的端确认收到这个报文段
超过某个时间还没有收到确认重发这个报文段
拥塞控制
作用于网络
慢开始和拥塞避免和快重传(Tahoe算法)
慢开始
初始发送报文段的数量为 1
之后每收到一个确认报文,发送报文端的数量就翻倍
直到到达慢开始门限,使用拥塞避免算法
拥塞避免
到达慢开始门限,每次发送报文段数量加1
当网络拥塞发生时,慢开始门限值减半,发送的报文段数量改变为 1
然后再次重复两种算法
快重传
接收方每收到一个失序的报文就立即发送重复确认
发送方立即重传对方未收到的 Msg 报文
可以提高网络的吞吐量
快恢复(Reno增加方法)
当发送方连续收到三个重复确认,执行乘法减小,慢开始门限值减半;
发送报文段的数量减半,然后执行拥塞避免算法,线性增加发送报文段的数量。
恢复应答判断(NewReno增加方法)
当丢失多个包时,Reno会不断减少自己的拥塞窗口
NewReno等到所有丢失的包被重发接收后才退出快速恢复
瓶颈带宽(BBR方法)
主动探测网络状态
发送多少报文和用多快的速度发送这些报文都是在每次反馈中不断调节
··· ···
TCP拆包粘包问题
MSS参数
最大报文段长度,就是TCP数据包每次能够传输的最大数据分段
避免IP分片,IPv4一般为536字节,IPv6一般为1220字节
选项只在初始化连接请求(SYN=1)使用
Nagle 算法
基本定义:任意时刻,最多只能有一个未被确认的小段(小于MSS的数据块)
发送端会先将第一个小包发送出去,后面到达的少量字符数据都缓存起来而不立即发送
发送条件
收到接收端对前一个数据包报文段的ACK确认
当前字符属于紧急数据
积攒到了一定数量的数据(达到MSS)
发生场景
发送方写入的数据大于套接字缓冲区的大小,此时将发生拆包
发送方写入的数据小于套接字缓冲区大小,并且触发Nagle算法,此时会发生粘包
当 TCP 报文的数据部分大于 MSS 的时候将发生拆包
接收方处理数据的速度赶不上发送端的速度,将发生粘包
何时处理
收到多个分组且分组之间毫无关系
当多个分组属于同一数据的不同部分时不需要处理
解决办法
在消息的头部添加消息长度字段
服务端获取消息头的时候解析消息长度,然后向后读取相应长度的内容
固定消息数据的长度
消息不够长时,空位补上固定字符
会浪费网络资源
设置消息边界
服务端从数据流中按消息边界分离出消息内容
一般使用换行符
其他特性
KEEPALIVE
场景:当链接很久没有数据报文传输时如何去确定对方还在线
当超过一段时间之后
TCP自动发送一个数据为空的报文给对方
如果对方回应了这个报文,说明对方还在线,链接可以继续保持
如果对方没有报文返回,并且重试了多次之后则认为链接丢失,没有必要保持链接
协议延迟
接收到对端的报文后,并不会立即发送ack
以便将ack和要发送的数据一块发送
linux采用动态调节算法来确定延时的时间
累计应答
为了保证顺序性,每一个包都有一个ID(序号)
建立连接的时候,会商定起始的ID是多少,然后按照ID一个个发送
为了保证不丢包,对应发送的包都要进行应答,但不是一个个应答
会应答某个之前的ID,该模式称为累计应答
heart-beat(应用层实现)
一般测试连接是否中断采用的时间间隔都比较短
很快的决定连接是否中断
可以自行决定当判断连接中断后应该采取的行为
大文件传输加速
连接优化
丢包,会进入重试,重试时间是 1s、2s、4s、8s 的指数递增间隔
缩短定时器可以让 TCP 在丢包环境建连时间更快
适用于高并发短连接的业务场景
平滑发包
在 RTT 内均匀发包
规避微分时间内的流量突发,尽量避免瞬间拥塞
丢包预判
有些网络的丢包是有规律性的
如果程序能自动发现这个规律(有些不明显),就可以针对性提前多发数据
减少重传时间、提高有效发包率
RTO探测
若始终收不到 ACK 报文,则需要触发 RTO 定时器
RTO 定时器一般都时间非常长,会浪费很多等待时间
而且一旦 RTO,拥塞窗口就会骤降(标准 TCP)
利用 Probe 提前与 RTO 去试探,可以规避由于 ACK 报文丢失而导致的速度下降问题。
带宽评估
单位时间内收到的 ACK 或 SACK 信息可以得知客户端有效接收速率
通过这个速率可以更合理的控制发包速度
带宽争抢
QUIC协议
定义
一种基于 UDP 的传输层协议。
QUIC = HTTP/2 + TLS + UDP
报文结构
header(明文)
Flags
Connection ID
QUIC Version
Packet Number
data(加密)
1个或多个frame
type(数据帧类型)
Stream
ACK
Padding
Window_Update
Blocked
··· ···
payload(应用数据)
连接
采用TLS握手,只需要一次RTT
客户端向服务端发送连接请求
客户端向客户段发送回应请求
握手成功,连接成功
可靠性保证
通过包号(PKN)和确认应答(SACK)来确认发送成功
与 TCP 相同的机制,包括流量控制、拥塞控制的四种算法。
协议间的区别
0 条评论
下一页