-
tcp
- 面向连接、可靠传输、点对点的、提供可靠交付、无差错、不丢失、不重复、按序到达。
- 全双工通讯,面向字节流,虽然每一次传递的都是tcp数据块
- 滑动窗口大小:swnd 接收窗口大小:rwnd 拥塞控制窗口大小:cwnd swnd = min(rwnd,cwnd*mss(最大分段大小))
- 如何保证可靠的?
- 超时重传 超时时间的确定
- 两种超时情况:发送的包没有被接收到,接收方接收到了,发送的ack包没有被发送方接收
- ARQ auto repeat-request 自动重新请求
- 停止等待ARQ 发送方发送一个帧之后,需要等到一个确认帧才能发送下一个
- 原理简单,但是等待时间较长,传输速度低
- 连续ARQ协议 发送方连续发送一组数据包,等待ack
- 回退n帧 接收端丢弃从第一个没有收到的数据包开始的所有数据包 发送端收到NACK后,从NACK中指明的数据包开始重新发送
- 选择性重传ARQ协议 只重传真正出错或者丢失的帧
- 校验和 校验成功也又可能出错
- 确认应答和序列号机制,可以将数据进行排序,去掉重复序列号的数据
- tcp连接的管理 三次握手和四次挥手
- 流量控制:防止接收端缓冲区饱和,造成丢包,超时重传。滑动窗口,tcp头部有一个16位的窗口大小值,是指接收端数据缓冲区的剩余大小,接受方随着ack包返回给发送方
- 如果接收方返回缓冲区大小为0,发送方停止发送数据,并发送窗口探测数据段,让接受方将窗口大小告诉发送端
- 拥塞控制:防止网络环境的限制,造成大量的丢包,超时重传,采用了拥塞窗口
- 慢启动和拥塞避免:慢启动指数增长,拥塞避免线性增长
- 快重传:收到三个连续的ack应答,将未收到应答的报文段立刻重传,不等超时。
- 快恢复:收到三个连续的ack,从当前窗口大小的一半进行拥塞避免
- 超时重传 超时时间的确定
- tcp的头部
- 源端口 2byte 目的端口 2byte 序列号seq 4byte 确认号ack 4byte
- 数据偏移 4位 表示tcp首部的偏移量、长度 单位是4字节 所以tcp首部最多60字节
- 控制位+保留位 12 位
- 窗口大小 2byte
- 校验和 2byte 紧急指针 2byte
- 选项 长度最大40字节
- 三次握手的流程以及为什么要三次握手?
- client发送syn = 1,seq = a 进入syn_sent状态
- server收到syn,发送 ack = a+1,syn = 1,seq = b,进入syn_recv状态
- client收到ack,发送ack = b+1,进入established状态 server收到ack后也进入established状态 完成三次握手
- 三次握手可以防止重复历史连接的初始化
- client发送新的syn,但是server收到了旧的syn,server回复了旧的,client会回复rst终止连接
- 四次挥手的流程
- client发送fin,seq=a 进入 fin-wait1状态
- server收到fin,发送ack = a+1,seq = b,进入closed—wait状态
- client收到ack,进入fin-wait2状态
- server发出fin,seq=c,进入last-ack状态
- client收到fin,发送ack = c+1,进入time-wait状态,间隔2msl(报⽂最大生存时间)进入close状态
- server收到ack,进入close状态
- 为什么要四次挥手
- tcp是全双工的,支持半关闭,可以一方结束发送后还可以接收另一方的消息
- 为什么要有time-wait
- 确保最后一个ack可以送达
- 防止具有相同四元组的旧数据包被接收
- 等待2MSL(两个报文最大生命周期),让延迟的数据都消失在网络中
- 服务器上有 timewait和closewait怎么办
- timewait表示自己主动关闭的连接,可以调整 /etc/sysctl.conf 使服务器可以快速回收和重用那些TIME_WAIT的资源
- 如果有大量的close-wait则比较严重,可能是程序出了问题 客户端断开连接 但是服务器没有断开连接
-
http
- cookie和session
- 由于http是无状态的,需要确认用户的身份,所以客户端请求的时候需要携带鉴别身份的标识。
- cookie是客户端存储用户信息的一种机制。
- 在响应报文头部会有set-cookie字段,客户端会保存cookie,之后发送请求时会带上cookie值一起发出去
- set-cookie的字段属性:
- name=value 指定cookie的名称和值
- domain=xx 指定域名,只有相同域名发送请求才会携带此cookie
- path=xx 域名中某个路径匹配时才携带此cookie
- expires=xx 过期时间
- Secure 仅https通信时才携带
- session存储在服务端,会生成一个sessionId,客户端请求的时候带上这个唯一的id,就可以检验身份,一般情况下这个id会存在客户端的cookie里面,客户端请求携带上检验身份
- http 0.9
- 单行协议 GET 加上请求的路径,没有头,没有版本信息,返回的也都是html文件 发送完毕就断开连接
- http 1.0
- 引入状态码,支持post和head请求
- 引入了请求头和响应头,有了content-type头,可以支持除html之外的其他类型
- 引入了缓存机制,通过状态码与If-Modified-Since、Expires等控制更新或使用本地缓存
- 协议版本信息会随着请求发送
- tcp连接没有复用
- http 1.1
- 支持了持久连接Connection:keep-alive,tcp连接默认不关闭,可以被多个请求复用,对于同一个域名,浏览器一般限制连接数到六以内。
- 新增了put delete等方法
- 同一个TCP连接里面,所有的数据通信是按次序进行的。服务器只有处理完一个回应,才会进行下一个回应。要是前面的回应特别慢,后面就会有许多请求排队等着。这称为"队头堵塞"(Head-of-line blocking)
- http2
- 不改变http的语义,方法、状态码、url以及首部字段,在传输上进行功能的提升
- http1.1的头部是文本,内容可以是二进制或者文本格式,http2是一个彻底的二进制协议
- 复用tcp连接,在一个连接里,客户端和服务端可以同时发送多个请求和响应,不用按照顺序一一对应。
- 使用头部压缩来较少开销
- 二进制分帧:在应用层和传输层之间新增了一个二进制分帧层,首部信息会放到headers帧,body放到data帧
- 帧是http2中最小的传输单位,以固定的8个byte头部开头 length 24位 type 8位 flags 8位 R保留位 1位 stream identifier 31位 之后是data ...
- 可以理解为该层把压缩后的数据解压缩,组装成为一个完整符合http1.x协议的请求
- h2c http over tcp 不使用 https
- cookie和session
rpc
rpc说明 juejin.cn/post/703818…
protobuff juejin.cn/post/684490…
websocket
-
弥补http 在持久通信能力上的不足,http本身是无状态的,无法满足双向通信,服务端无法主动通知到客户端,需要客户端轮询才可以保证实时性的消息传递。
-
websocket是应用层协议,是全双工的,避免频繁建立http连接来节省资源,提高效率,使用单个tcp连接来进行双向传输。
-
websocket基于最小帧结构进行设计,可以和http共用一个服务,增加了一个地址和协议命名机制实现在同一个端口上支持多个服务,提供了一个简单的和http共存的,依赖于http 基础设施(如代理等)。
-
优点
- 控制开销小,在建立连接,交换数据时不需要像http一样携带完整头部,用于协议控制的头部较小。
- 实时性强,不需要客户端轮询服务端获取数据。
- 可以保持长连接的状态,websocket使用心跳维持创建连接,之后通信时可以省略部分握手的状态信息。
- 包含一个设计用于处理代理和其他网络中介的情况,以及额外的结束握手协议。
-
websocket是基于tcp通信的,本质上是tcp协议的长连接,websocket协议独占一条tcp通道,从tcp流确认消息边界,解析出每个独立的消息包,通过ping/pong Frame 数据包维持连接状态。
-
握手:websocket通过http1.1的101状态码发起websocket连接的升级请求,之后服务器回应同意升级,达成ws连接建立
- 先通过三次握手建立http连接 头部 Upgrade:websocket Connection:Upgrade 等头部指定需要的ws版本等信息 Sec-WebSocket-Key 随机字符串 服务端处理后返回 Sec-WebSocket-Accept 头的值,可以避免普通http请求被误认为 WebSocket协议
- 客户端发送握手帧,服务端发送握手回应帧 网络状态码 101 Switch Protocols Upgrade:websocket Connection:Upgrade Sec-WebSocket-Accept:xxxxx
- 建立连接成功,可以互相通信
-
数据帧分析
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-------+-+-------------+-------------------------------+
|F|R|R|R| opcode|M| Payload len | Extended payload length |
|I|S|S|S| (4) |A| (7) | (16/64) |
|N|V|V|V| |S| | (if payload len==126/127) |
| |1|2|3| |K| | |
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
| Extended payload length continued, if payload len == 127 |
+ - - - - - - - - - - - - - - - +-------------------------------+
| |Masking-key, if MASK set to 1 |
+-------------------------------+-------------------------------+
| Masking-key (continued) | Payload Data |
+-------------------------------- - - - - - - - - - - - - - - - +
: Payload Data continued ... :
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Payload Data continued ... |
+---------------------------------------------------------------+
- FIN 标记符 是否为消息的最后一个数据帧
- REV 标志位 一般都是0
- opcode 帧类型
- mask 掩码 默认为1 客户端向服务端发送数据 需要进行掩码操作 服务端向客户端 不需要
- payload len 数据的长度 7位 或者7+16 或者7+64
- payload data 数据
- opcode 帧类型
- 0x0 持续帧
- 0x1 文本帧
- 0x2 二进制帧
- 0x3 - 7 预留给以后的非控制帧
- 0x8 连接关闭
- 0x9 ping
- 0xA pong
- 0xB - F 预留给以后的控制帧