拆包和粘包是在socket编程中经常出现的情况,在socket通讯过程中,如果通讯的一端一次性连续发送多条数据包,tcp协议会将多个数据包打包成一个tcp报文发送出去,这就是所谓的粘包。而如果通讯的一端发送的数据包超过一次tcp报文所能传输的最大值时,就会将一个数据包拆成多个最大tcp长度的tcp报文分开传输,这就叫做拆包。
- Client:SYN, seq num = client_isn
- Server: ACK+SYN, ack num = client_isn+1, seq num = server_isn
- Client:ACK, ack num = server_isn+1
为什么需要三次握手?
- 三次握⼿才可以阻止重复历史连接的初始化
- 三次握⼿才可以同步双⽅的初始序列号
- 三次握⼿才可以避免资源浪费
- Client:FIN
- Server:ACK
- Server:FIN
- Client:ACK
为什么需要四次挥手?
- 保证正确断开,需要ACK
- 单向断开,FIN只是说明不再发送数据了
主动关闭连接的,才会有TIME_WAIT状态 TIME_WAIT时长2MSL(报⽂最⼤⽣存时间)
为什么需要timewait?
- 经过 2MSL 这个时间,⾜以让两个⽅向上的数据包都被丢弃,使得原来连接的数据包在⽹络中都⾃然消失,再出现的数据包⼀定都是新建⽴连接所产⽣的
- 等待⾜够的时间以确保最后的 ACK 能让被动关闭⽅接收,从⽽帮助其正常关闭
高并发短连接问题 产生原因
- 高并发短连接
- 高并发可以让服务器在短时间内占用大量端口号
- 短连接表示业务处理时间+数据传输时间远小于TIME_WAIT的时间(GET一个页面)
解决
- 打开系统的TIMEWAIT重用和快速回收
- 增大对外连接的端口范围
- 增大SYN队列大小
- 做负载均衡,多个服务器处理请求
TCP
- 面向连接
- 一对一
- 可靠交付
- 拥塞控制和流量控制
- 首部更长(至少20字节)
- 流式传输,无边界,保证顺序
- TCP 的数据⼤⼩如果⼤于 MSS ⼤⼩,则会在传输层进⾏分⽚,数据丢失只传输丢失的分片
- HTTP、FTP、POP3、SMTP、SSH
UDP
- 无连接
- 多对多
- 尽最⼤努⼒交付
- 首部短,8字节
- 是⼀个包⼀个包的发送,是有边界的,但可能会丢包和乱序
- UDP 的数据⼤⼩如果⼤于 MTU ⼤⼩,则会在 IP 层进⾏分⽚,数据丢失需要重传所有数据包
- DNS、NTP、DHCP
- 序列号
- 确认应答
- 重传控制
- 超时重传
- 设定超时时间,过期重传
- 超时重传时间 RTO 的值应该略⼤于报⽂往返 RTT 的值
- 每当遇到⼀次超时重传的时候,都会将下⼀次超时时间间隔设为先前值的两倍。两次超时,就说明⽹络环境差,不宜频繁反复发送
- 快速重传
- 不以时间为驱动,⽽是以数据驱动重传
- 收到三个同样的ACK,产生重传
- 问题是不知道该丢失报文后面的报文有没有收到?
- SACK
- TCP option加字段SACK
- 只重传丢失的数据
- ACK的机制也是和快速重传一样,发送方收到三个相同的ACK开始重传,但是SACK会指定已经收到的报文,所以只需要发送ACK这一部分就可以
- D-SACK
- 原理和SACK一样的
- 可以让「发送⽅」知道,是发出去的包丢了,还是接收⽅回应的 ACK 包丢了
- 可以知道是不是「发送⽅」的数据包被⽹络延迟了
- 可以知道⽹络中是不是把「发送⽅」的数据包给复制了
- 超时重传
- 连接管理
- 窗口控制
- 半连接队列
- SYN 队列
- 服务端收到客户端发起的 SYN 请求后,内核会把该连接存储到半连接队列,并向客户端响应 SYN+ACK
- 接着客户端会返回 ACK,服务端收到第三次握⼿的 ACK 后,内核会把连接从半连接队列移除
- 全连接队列
- accept 队列
- 然后创建新的完全的连接,并将其添加到 accept 队列,等待进程调⽤ accept 函数时把连接取出来
- GET - 请求指定的页面信息,并返回实体主体。
- POST - 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。
- DELETE - 请求服务器删除指定的页面。
- PUT - 从客户端向服务器传送的数据取代指定的文档的内容。
- OPTIONS - 允许客户端查看服务器的性能,获取服务器支持的HTTP请求方法。
- 1** - 信息,服务器收到请求,需要请求者继续执行操作
- 2** - 成功,操作被成功接收并处理
- 3** - 重定向,需要进一步的操作以完成请求
- 4** - 客户端错误,请求包含语法错误或无法完成请求
- 5** - 服务器错误,服务器在处理请求的过程中发生了错误
- http1.0
- http1.1
- 使⽤ TCP ⻓连接的⽅式改善了 HTTP/1.0 短连接造成的性能开销
- ⽀持管道(pipeline)⽹络传输,只要第⼀个请求发出去了,不必等其回来,就可以发第⼆个请求出去,可以减少整体的响应时间
- 如何优化?
- 避免发送http请求
- 本地缓存资源
- 减少http请求次数
- 代理服务器重定向
- 合并请求
- 延迟发送请求(不是一次性加载全部页面)
- 减小http响应数据大小
- 有损压缩
- 无损压缩
- 避免发送http请求
- http2
- 头部压缩
- 二进制帧
- 并发传输
- 服务器主动推送资源
- http3
- UDP
优点
- 简单,灵活,易于扩展:因为无太多限制,因为简单可以叫用户自己扩展
- 应用广泛,环境成熟:因为过于简单,普及,因此应用很广泛。因为本身不属于一种语言,因此,就无平台,语言界限,因此跨平台性很强
- 无状态,因为没有任何记录。可以减轻服务器的负担,能够更多的cpu和内存用来对外提供服务。因为无状态,对服务器无要求,因此可以组成集群
缺点
- 明文不安全
- 因为无状态,因此无法做连续多个步骤的操作。例如:加入购物出,结算,支付。每次都需要验证身份信息,但是无状态所以无法连续。解决办法,就是cookie技术
- 性能:“请求 - 应答”模式则加剧了 HTTP 的性能问题,这就是著名的“队头阻塞”(Head-of-line blocking),当顺序发送的请求序列中的一个请求因为某种原因被阻塞时,在后面排队的所有请求也一并被阻塞,会导致客户端迟迟收不到数据。为了解决这个问题,就诞生出了一个专门的研究课题“Web 性能优化”,HTTP 官方标准里就有“缓存”一章(RFC7234),非官方的“花招”就更多了,例如切图、数据内嵌与合并,域名分片、JavaScript“黑科技”等等
- 混合加密:在通信建⽴前采⽤⾮对称加密的⽅式交换「会话秘钥」,在通信过程中全部使⽤对称加密的「会话秘钥」的⽅式加密明⽂数据
- 摘要算法:摘要算法⽤来实现完整性,能够为数据⽣成独⼀⽆⼆的「指纹」
- 数字证书
- 签发过程
-
- CA打包服务器公钥、有效时间等信息,并hash
-
- CA用自己的私钥对hash值签名
-
- 最后将 Certificate Signature 添加在⽂件证书上,形成数字证书
-
- 客户端验证过程
-
- 使用同样的hash算法得到该证书的hash值H1
-
- 使用CA的公钥解密签名,得到H2
-
- H1==H2,可信
-
- 签发过程
- SSL/TLS 协议
- Client: client hello
- TLS版本号
- 支持的密码套件
- 生成的client random
- Server: server hello
- 确认的TLS版本号
- 使用的密码套件
- 生成的server random
- 数字证书
- Client:
- 验证服务器的数字证书
- Client_1: RSA公钥加密的pre_master
- Client_2: 告诉服务器开始使用会话密钥加密
- Client_3: 把之前交互的所有数据做摘要并发送
- Server:
- 告诉客户端开始使用会话密钥加密
- 把之前所有的数据做加密发送
- 先查看本地计算机缓存,有的话无后面操作
- 本地计算机缓存没有的话,在本地DNS服务器查找,如果找到的话,就将记录返回给客户机
- 本地DNS服务器没有的话,将请求发送给根DNS服务器,根DNS服务器解析根域名,将一级(顶级)DNS服务器的IP地址返回给本地DNS服务器
- 本地DNS服务器向顶级DNS服务器发出请求
- 顶级DNS服务器将权限DNS服务器IP地址返回给本地DNS服务器
- 本地DNS服务器向权限DNS服务器发出请求
- 权限DNS服务器将所查询的IP地址返回给本地DNS服务器
- 本地DNS服务器将此IP地址返回给客户机
查询方式: 1.递归查询:主机 向 本地DNS服务器的查询 2.迭代查询:本地DNS服务器向根域名服务器的查询
IP包:源地址-目的地址 MAC帧:一层一层修改,ARP解析下一跳的MAC地址
在服务器故障时,TCP连接不会立刻断开,如果有keepalive机制,会在keepalive超时时断开连接