小林coding计算机网络知识点总结


前言

记录小林的图解网络部分重点知识,方便日后翻阅回看。
不一定面面俱到,也不会尽数记录,多半将需要辨析和对比的内容采用自己理解的方式来记录。
主要来源:小林codingJavaGuide,感谢大佬对知识的总结
有其他引用的会标注出来。


名词科普

网络号:负责标识该 IP 地址是属于哪个「子网」的。
主机号:负责标识同一「子网」下的不同主机。
MSS(Maximum Segment Size):最大报文长度,TCP协议定义的一个选项,MSS是TCP用来限制应用层最大的发送字节数。
MTU(Maximum Transmission Unit):最大传输单元,是数据链路层的概念,大小为1500字节。表示可以传输的最大数据包(数据块+TCP头+IP头,不包含帧首部和尾部)。当网络包超过 MTU 的大小,就会在网络层分片,以确保分片后的 IP 包不会超过 MTU 大小。
幂等:多次执行相同的操作,结果都是相同的。
URI:统一资源标志符,可唯一标识资源。
URL:统一资源定位符。是URI的子集,还提供了如何定位资源的信息(即资源的访问方式)。
RFC(Requests for Comments):请求注解文档。用于发布Internet标准和Internet其他正式出版物的一种网络文件,是关于某项技术官方维护的最全面、最权威的文档。一个RFC文件在成为官方标准前,至少经过建议标准草案标准因特网标准三个阶段。
SSL(Secure Socket Layer)安全套接字层
||
TLS(Transport Layer Security)传输层安全协议
RTT(Round-Trip Time):往返时延。是指数据从网络一端传到另一端再收到接收端确认所需的时间。
MAC地址(Media Access Control Address):媒体存取控制位址,也叫局域网地址 / 以太网地址 / 物理地址 / 硬件地址,用来确认网络设备位置。在OSI模型中,第三层网络层负责IP地址,第二层数据链路层负责MAC地址,用来唯一标识一张网卡
MSL(Maximum Segment Lifetime)报文最大生存时间。任何报文在网络上存在的最长时间,超过后将被丢弃。
TTL(Time to Live)指网络层一个网络数据包的生存周期,只要一个路由器处理过这个数据包,它就递减这个数据包的寿命计数,当寿命计数递减到0的时候,路由器就丢弃该包。
RTO(Retransmission Timeout)超时重传时间,通常略大于RTT


一、基础篇

1.1 TCP/IP网络模型

以下并非严格意义的TCP/IP模型,网络接口被分成两层。

层级功能主要协议
应用层专注于为用户提供应用功能,不关心数据如何传输(在用户态工作,往下是内核态)HTTP、FTP、
DNS、(SMTP -> IMAP)、Telnet、SSH、NFS、DHCP(工作)
传输层负责向两台终端设备进程之间的通信提供通用的数据传输服务。TCP、UDP
网络层实际的传输功能,为分组交换网上的不同主机提供通信服务;选择合适的路由IP、ICMP、IGMP、NAT(路由的网络地址转换协议)
数据链路层(网络接口)数据链路层的作用是将网络层交下来的 IP 数据报组装成帧,在两个相邻节点间的链路上传送帧ARP、RARP
物理层(网络接口)实现相邻计算机节点之间比特流的透明传送,尽可能屏蔽掉具体传输介质和物理设备的差异

应用层协议:

基于TCP的应用层协议基于UDP的应用层协议
HTTP、FTP、SMTP、TELNET、SSHDNS、SFTP(简单)、SNMP(简单)

为什么要分层?

  1. 各层之间相互独立
  2. 提高整体灵活性
  3. 大问题化小

封装格式(from小林)

传输单位: 网络接口层–>帧(frame),IP 层–>包(packet),TCP 层–>段(segment),HTTP–>报文(message)。但这些没有本质区别,可以统称为数据包

1.2 键入网址到网页显示,期间发生了什么?

  1. 解析URL:首先浏览器要解析URL,URL包括协议 + web服务器 + 目录名和文件名,继而生成发送给web服务器的、对该资源的请求信息
  2. DNS解析:查询服务器域名对应的 IP 地址。DNS服务器保存了 Web 服务器域名与 IP 的对应关系。客户端发送DNS请求给本地DNS服务器,查询对应的IP地址后返回客户端。PS:需要查询时,浏览器、操作系统、hosts文件依次看有没有缓存,不一定每次都要解析IP。
  3. TCP连接:HTTP报文是基于TCP传输的,涉及到三次握手。组装好TCP报文后交给网络层处理。
  4. 发送HTTP请求
       (1) 加入IP头部,生成IP报文
       (2) 加入MAC头部。(发送方MAC地址在网卡里,接收方的MAC地址靠ARP协议在以太网广播寻找,当然也是有缓存的)
       (3) 再经过网卡交换机路由器,抵达服务器
  5. 服务器处理请求并返回HTTP报文:服务器依次检查MAC头部IP头TCP头检查序列号和端口号,HTTP进程收到后把这个网页封装在HTTP响应报文里并返回(相同步骤)。
  6. 浏览器解析渲染页面:浏览器是一个边解析边渲染的过程。
  7. 连接结束

二、HTTP

2.1 常见面试题

HTTP常见状态码

  • 1xx 提示信息 协议处理的一种中间状态,表示接收的请求正在处理。
  • 2xx 成功 服务器正常收到客户端的请求,并处理完毕。
    200 OK 是最常见的成功状态码,表示一切正常。如果是非 HEAD 请求,服务器返回的响应头都会有 body 数据。
    204 No Content与 200 OK 基本相同,但响应头没有 body 数据。
    206 Partial Content 应用于 HTTP 分块下载或断点续传,表示响应返回的 body 数据并不是资源的全部,而是其中的一部分。
  • 3xx 重定向 表示客户端请求的资源发送了变动,需要客户端用新的 URL 重新发送请求获取资源。
    301 Moved Permanently永久重定向。说明请求的资源已经不存在了,需改用新的 URL 再次访问。
    302 Found临时重定向。说明请求的资源还在,但暂时需要用另一个 URL 来访问。
    301 和 302 都会在响应头里使用字段 Location,指明后续要跳转的 URL,浏览器会自动重定向新的 URL。
    304 Not Modified不具有跳转的含义,表示资源未修改,重定向已存在的缓冲文件,也称缓存重定向,也就是告诉客户端可以继续使用缓存资源,用于缓存控制。
  • 4xx 客户端错误 表示客户端发送的报文有误,服务器无法处理,也就是错误码的含义。
    400 Bad Request表示客户端请求的报文有错误,但只是个笼统的错误。
    403 Forbidden表示服务器禁止访问资源,并不是客户端的请求出错。
    404 Not Found表示请求的资源在服务器上不存在或未找到,所以无法提供给客户端。
  • 5xx 服务器错误 表示客户端请求报文正确,但是服务器处理时内部发生了错误。
    500 Internal Server Error与 400 类似,是个笼统通用的错误码,服务器发生了什么错误,我们并不知道。
    501 Not Implemented表示客户端请求的功能还不支持,类似“即将开业,敬请期待”的意思。
    502 Bad Gateway通常是服务器作为网关或代理时返回的错误码,表示服务器自身工作正常,访问后端服务器发生了错误。
    503 Service Unavailable表示服务器当前很忙,暂时无法响应服务器,类似“网络服务正忙,请稍后重试”的意思。

HTTP/1.1常见字段

通用首部字段请求首部字段:
用于补充请求的附加信息、客户端信息、响应内容优先级
响应首部字段:
用于补充响应的附加信息、服务器信息和对客户端的附加要求
实体首部字段:
实体部分使用的首部,补充与实体相关的信息
Cache-Control:对缓存进行操作
Connection:管理持久连接;控制代理不再转发的首部字段
Date:报文创建时间
Pragma:历史遗留
Trailer:应用于分块传输编码时,说明主体内有什么字段
Transfer-Encoding:规定了传输报文体时采用的编码方式
Upgrade:指定另外一个通信协议;另需Connection:Upgrade
Via:追踪请求和响应报文的传输路径
Warning:给出缓存相关的警告
Accept:通知用户代理可以处理的媒体类型和优先级;可用q来表示权重
Accept-Charset:指定用户代理支持的字符集
Accept-Encoding:用户代理支持的编码和优先级
Accept-Language:用户代理能够处理的自然语言和优先级
Authorization:用户代理的认证信息
Except:期望出现的特定行为
From:告知用户的电子邮件地址
Host:指定服务器域名,包括请求资源所处的主机名端口号(必须包含,因为同一IP地址可能有多个域名
条件请求:
If-Match:与ETag的值匹配时服务器才接受
If-None-Match:和ETag不一致的时候才接受(相反)
If-Modified-Since:如果在这个指定时间后资源更新了,才接受
If-Unmodified-Since:这个时间后没更新才接受(相反)
If-Range:如果指定的ETag或时间匹配上了,则返回范围请求(后面必须有Range);否则返回全部资源
Max-Forwards:指定在代理服务器间的转发次数,每传送一次就-1
Proxy-Authorization:接受到代理服务器发来的认证时,客户端告知服务器认证所需信息
Range:只获取部分资源(字节-字节)
Rferer:告知服务器请求原始资源的URI
TE:指定传输编码方式和优先级(和Accept-Encoding很像,但属于传输编码)
User-Agent:将浏览器、用户代理名称传给服务器
Accept-Ranges:告知能否处理范围i请求:bytes/none
Age:创建响应过去了多久
ETag:告知客户端实体标识
Location:配合3XX,提供重定向的URI
Proxy-Authenticate:把代理服务器要求的认证信息发给客户端(客户端-代理)
WWW-Authenticate:告知客户端适用于访问请求URI资源的认证方案(客户端-服务器)
Retry-After:告知客户端应该在多久之后再次请求
Server:告知客户端当前服务器上的HTTP服务器应用程序的信息
Vary:如果使用的Accept-Language值相同,就直接从缓存返回响应;反之则需要从源服务器获取资源才返回响应
Allow:通知客户端支持访问资源的HTTP方法
Content-Encoding:告知客户端,自己返回的数据使用了什么压缩格式
Content-Language:告诉客户端实体主体所用自然语言
Content-Length:表明实体主体部分的大小
Content-Location:表示报文主体返回资源的URI
Content-MD5:一段由MD5算法生成的值,检测主体是否保持完整
Content-Range告知客户端响应返回哪个部分
Content-Type:说明了实体主题内对象的媒体类型
Expires:将资源失效的日期告知客户端
Last-Modified:资源的最终修改时间

Host 客户端发送请求时,用来指定服务器的域名。
Content-Length服务器在返回数据时,会有 Content-Length 字段,表明本次回应的数据长度。
Connection 最常用于客户端要求服务器使用 TCP 持久连接,以便其他请求复用。HTTP/1.1 版本的默认连接都是持久连接,但为了兼容老版本的 HTTP,需要指定 Connection 首部字段的值为 Keep-Alive。
Content-Type服务器回应时,告诉客户端,本次数据是什么格式。客户端请求的时候,可以使用 Accept字段声明自己可以接受哪些数据格式。
Content-Encoding表示服务器返回的数据使用了什么压缩格式。客户端在请求时,用 Accept-Encoding字段说明自己可以接受哪些压缩方法。
ETag:一种将资源以字符串形式做唯一性标识的方式,服务器为每份资源分配对应的ETag值;资源更新时候,ETag值也更新。例如:Google中英文网页的URI虽然相同但对应的ETag不同。

GET和POST区别

安全:是指请求方法不会「破坏」服务器上的资源
幂等:多次执行相同的操作,结果都是「相同」的。
《post和put的区别》:PUT是幂等的,相当于x = 1;而POST不是幂等的,因为相当于上传资源。

方法GETPOST
语义请求获取指定的资源(只读)对指定的资源做出处理(新增或提交数据)
安全性安全、幂等不安全、不幂等
缓存可被缓存一般不会缓存
请求数据位置一般写在URL中一般写在报文 body 中

如果不照RFC规范定义的语义来实现的话, 上述都不一定。
它们是 HTTP 请求协议的请求方法,而 HTTP 又是基于TCP/IP的关于数据如何在万维网中如何通信的协议,所以 GET/POST 实际上都是 TCP 链接。

强制缓存和协商缓存

缓存技术强制缓存协商缓存
特点浏览器判断没过期,则使用缓存(浏览器主动)状态码304,告知客户端是否可以使用缓存(与服务端协商)
字段Cache-control:相对时间(优先级高)
Expires:绝对时间
请求If-Modified-Since和响应Last-Modified:如果在这个时间后更新了才接受 & 响应资源最后修改时间
请求If-None-Match和响应ETag:和ETag不一致的时候才接受(ETag优先级高)
结果如果最后修改时间较新,则返回最新资源 200
否则返回304
如果资源变化了返回200,否则返回304

HTTP1.1

优点

  1. 简单
  2. 灵活易扩展(例如HTTPS和HTTP/3对TCP层的修改)
  3. 应用广泛,跨平台

缺点

  1. 无状态——Cookie解决
  2. 不安全
    • 明文传输 - 被窃听
    • 不验证通信方身份 - 被冒充和伪装
    • 不校验报文完整性 - 被篡改

性能(和HTTP1.0相比的优势)总之一般般

优点 1. 长连接——减少重复操作的开销
优点 2. 管道网络传输——不等回应即可发送第二个请求,减少响应时间
缺点 3. 队头阻塞 (2.没有解决的缺点)

HTTPS

HTTP的通信接口部分用SSL和TLS协议代替 == HTTPS(即HTTP + 加密 + 认证 + 完整性保护)

协议HTTPHTTPS
安全性明文传输TCP 和 HTTP 之间加入了 SSL/TLS 安全协议,加密传输报文
连接三次握手三次握手+SSL/TLS握手
端口号80443

另外HTTPS需要向CA申请数字证书来确保服务器的身份

如何解决HTTP的安全问题:

  • 明文传输产生的窃听问题——信息加密 (混合加密)
  • 不验证身份产生的冒充问题——校验机制 (证书)
  • 不校验完整性产生的篡改问题——身份证书 (摘要算法)

常见非对称加密算法:RSA、DSA、ECC、DH
对称:DES、3DES、AES、RC(记:RC或者ES结尾的是对称)

HTTP的演变

协议HTTP/1.1HTTP/2HTTP/3(QUIC的特点)
改进1.长连接
2.管道运输:一次发送多个请求
3.废弃了两种请求方法LINK和UNLINK,新增了CONNECT、OPTIONS和TRACE
4.新增了大量状态码
1.头部压缩(解决1)
2.进制格式
3.数据流:可以乱序发送,后stream ID组成HTTP信息
4.多路复用,串行变成并发(解决2)
5.服务器推送(解决3)
TCP->UDP+ QUIC
1.无队头阻塞
2.更快的连接建立(QUIC包含TLS,只需1个RTT)
3.连接迁移
不足1.头部冗长,未经压缩,浪费带宽,造成延迟
2.没有请求优先级,所以队头阻塞(HTTP层)
3.服务器只能被动接收客户端的请求
TCP层队头阻塞
TCP和TLS握手时延
普及慢,很多网络设备不识别QUIC

HTTP演变

2.2 HTTP 加密算法

RSA握手

即常规的混合加密机制:交换密钥环节使用公开密钥(非对称) 加密,建立通信交换报文阶段使用共享密钥(对称) 加密。

特点:传统密钥交换算法,不具备前向安全(服务端私钥泄漏后会被破解)

ECDHE握手

ECDHE具有前向安全,被广泛使用,由DH算法演变


  • DH算法 基于离散对数:即在对数基础上加上取模运算
    效果:知道对数就可以计算出真数,但知道真数却很难推出对数

举例:小明和小红确定了P和G(公开),各自生成了随机整数a和b作为私钥,别人不知道,他们俩根据P、G、a/b分别计算出了公钥A和B,并交换A和B。根据离散对数的交换律,他们俩分别用A+b和B+a计算时,可以得到相同的K,这个K就是对称加密密钥,可以作为会话密钥。

整个协商过程中,小红和小明只公开了P、G和各自的A/B(公钥),没有公开a/b(私钥),黑客是无法计算出来的。


  • DHE:因为DH交换时服务器的公钥不变,所以有可能被破解出私钥。干脆每次交换时都随机生成临时的私钥,也就是DHE算法(ephemeral临时性的

  • ECDHE:利用EDC椭圆曲线,更容易计算出公钥和最终的会话密钥
    大概如下:双方确定好椭圆曲线和基点,各自生成私钥d,并和基点处理得到公钥Q;双方交换公钥,因为椭圆曲线满足乘法交换律,所以x坐标是一样的,是共享密钥(会话密钥)。

特点:私钥随机生成,根据公开信息也很难破解私钥。

四次握手

  1. 客户端发送TLS版本号、支持密码套件列表和随机数a
  2. 服务端确认版本号、加密方法(ECDHE),并给出随机数b;此外,生成随机数(椭圆曲线私钥),给出椭圆曲线和公钥(私钥和椭圆曲线计算),附带用RSA给椭圆曲线做的签名证书
  3. 客户端校验证书,生成一个随机数作为客户端椭圆曲线的私钥,计算得到客户端公钥并发给服务端。
    至此,双方都有对方的椭圆曲线公钥、自己的私钥和曲线,于是都算出来了坐标x,用a+b+x作为最终会话密钥。
    客户端再说明一下之后要加密,和摘要等等
  4. 服务端说明之后加密,和摘要。

区别:

ECDHE
1.支持前向保密
2.客户端可以不用等最后一次握手,就提前发出加密的数据。因为RSA中,服务端要等到客户端第三次握手把密钥发过去后才可以通信,而ECDHE中,两方在第二和第三次握手已经确定好了会话密钥

2.3 HTTP 1.1如何优化?

三个角度优化

三个角度具体优化方法
避免发送HTTP请求缓存
客户端第一次请求及数据保存在本地磁盘,形成<key,value>
过期?在请求的ETag带上第一次请求中响应头部的摘要,服务器收到后会与本地资源的摘要作比较,如果相同则返回不含包体的304 Not Modified
减少请求次数1. 减少重定向请求次数:利用中间的代理服务器知晓规则
2. 合并请求:合并资源,如CSS、webpack
3. 延迟发送请求:按需获取,滑动页面的时候再获取资源
减少服务器响应数据大小无损压缩:gzip。请求Accepy-Encoding,响应Content-Encoding(文本、程序代码)
有损压缩:舍弃一些数据(质量)。请求Accept中的q质量因子(音视频、图片)

2.4 HTTPS 如何优化?

  1. 硬件优化、软件优化:HTTPS 协议是计算密集型,而不是 I/O 密集型,所以不能把钱花在网卡、硬盘等地方,应该花在 CPU
  2. 协议优化
      (1)用ECDHE替换RSA,往返1RTT,
      (2)TLS 1.2->TLS 1.3,往返1RTT;在Hello时就发送椭圆曲线,且废除RSA和DH
  3. 证书优化
      (1)证书选择:椭圆曲线证书比RSA密钥长度短
      (2)证书验证优化:OCSP(Online Certificate Status Protocal)、OCSP Stapling
  4. 密钥缓存(无前向安全,且易被重放攻击)
      (1)Session ID:双方缓存密钥,Session ID和密钥相当于key-value。但是也有缺点,首先是每一个客户端都要保存密钥,其次是现在网站一般多服务器,不一定命中上次的服务器
      (2)Session Ticket:客户端负责缓存。
      (3)Pre-shared KeyTLS 1.3重连只需要0 RTT。重连时Ticket和HTTP一起发给服务端

解决重放攻击,应给密钥设定过期时间

2.5 HTTP 2 提高传输效率、吞吐能力

兼容HTTP 1.1

没有在URL改变协议名字,只在应用层做了改变,还是基于TCP传输,但是把HTTP分解成了语义语法,语义没变,还是请求方法、状态码和头字段等,语法有很多改变。

头部压缩 (解决头部冗长问题)

HPACK取代gzip

  1. 静态表:首先两端维护一个字典,用索引号index代替字段名(GET,200,https等),共61种高频字符串
  2. 动态表:发送新首部时在静态表里添加索引号
  3. Huffman编码:关于首部字段的内容用哈夫曼编码代替,基于二进制编码,不需要\r\n,改用表示字符串长度的Value Length

二进制帧

二进制+位运算

并发传输(解决队头阻塞问题)

多个Stream复用一条TCP连接,达到并发效果;每个帧头携带Stream ID,同一Stream内部的帧严格有序,方便接收后组装;还可以设置优先级,比方说先传递HTML再传递图片

包含关系:TCP连接 > Stream > Message >Frame

服务器主动推送(解决不支持服务器推送问题)


但是HTTP2是基于TCP传输数据的,TCP是字节流协议,必须保证字节数据是完整连续的,内核才会将缓冲区的数据给HTTP应用,这方面存在阻塞,因此改用UDP,即HTTP 3

2.6 HTTP 3

之前存在的问题:

  1. 队头阻塞:TCP丢包时,整个TCP都要等待重传
  2. 握手延迟:发起HTTP请求时,需要经过TCP+TLS总计3RTT时延
  3. 网络迁移需要重新连接:4G切WiFi时要重新握手,因为IP地址和端口变动了

QUIC协议特点:

  1. 无队头阻塞,Stream之间没有依赖
  2. 更快建立连接:QUIC包含TLS,只需要1RTT即可握手
  3. 连接迁移:通过连接ID标记两个端点,而不是IP地址和端口

其他:HPACK升级->QPACK,静态表91项

三、TCP

3.1 三次握手、四次挥手

TCP头格式

TCP基本认识

TCP特点
为什么需要TCP?IP层不可靠,不保证网络包的交付和数据完整性
TCP确保无损坏、无间隔、非冗余、按序
连接的基本共识Socket:IP号 + 端口号
序列号:解决乱序问题
窗口大小:流量控制
如何唯一确定?四元组
地址字段在IP头,端口字段在TCP头
TCP最大连接数?理论上max = 客户端IP数 * 客户端端口数,实际受FD和内存的限制
TCPUDP
连接和方式面向连接、可靠、字节流无连接、不可靠、数据报
连接对象一对一(单播)一对一、一对多、多对一、
多对多(单播多播广播)
拥塞控制有拥塞控制
首部开销至少20字节8字节
分片机制如果HTTP消息比MSS长,就要在传输层分片UDP数据如果大于MTU,在IP层分片
使用场景实时应用,包括:
音视频、多媒体
包总量少的通信,如DNSSNMP
FTP文件传输、HTTP/S

三次握手
在这里插入图片描述

为什么是三次握手
  (1)避免历史连接:如果因为宕机重发,最好在「被动发起方」建立连接前阻止历史连接,就不会资源浪费,而这样就需要三次握手
  (2)同步双方初始序列号序列号作用:不重复、不丢弃、按序传输
  (3)避免资源浪费:服务端每收到一个SYN只能建立一个连接(因为不知道客户端是否收到自己的ACK),可能有冗余连接

初始化序列号不一样?
  为了防止历史报文被下一个相同四元组的连接接收。有时前一条数据因故阻塞,恰好服务端断电重启了,再重新建立连接,之前阻塞的消息再到达后会出bug。总而言之,为了防止上一次连接的数据被下一次连接接收

TCP为什么需要MSS?
先看定义:
  MTU:一个网络包的最大长度,以太网中一般为 1500 字节;
  MSS:除去 IP 和 TCP 头部之后,一个网络包所能容纳的 TCP 数据的最大长度;
IP没有超时重传机制,如果有一个IP分片丢失,那么整个IP报文分片都得重传;所以为了传输效能,TCP建立连接时协商MSS值,由此分片后IP包也不回大于MTU,此后如果一个TCP分片丢失了,重发时也只是以MSS为单位。

第一次握手丢失了,发生什么?

客户端重传第一次握手SYN报文。第一次超时重传是在1秒后,每次重传时间是上一次的2倍,第5次重传(重传次数由内核参数决定)后,会等待32秒,如果还没回应就断开连接

第二次握手丢失了,发生什么?

两边都会重传:
 客户端重传第一次握手SYN报文,最大重传次数由tcp_syn_retries内核参数决定
 服务端重传第二次握手SYN-ACK报文,最大重传次数由tcp_synack_retries内核参数决定

第三次握手丢失了,发生什么?

服务端重传第二次握手SYN-ACK报文。

SYN攻击
攻击者伪造不同IP发送SYN报文,服务端发出去的ACK+SYN 无应答,占满半连接队列
避免方式:

  1. 修改Linux内核参数,控制队列大小和队满处理方式
  2. tcp_syncokies方法。半连接队列满了后,新收到的SYN包计算出cookie值,返回给客户端;再收到客户端的应答报文时,检查合法性后直接放入全连接队列。

四次挥手
在这里插入图片描述

为什么需要四次
假设客户端主动关闭连接。
客户端发送FIN时,仅仅表示客户端不发数据了,但还能接收数据。
服务端可能还有数据处理发送,待不再发送时,才回FIN给客户端

第一次挥手丢失了,发生什么?
重传第一次挥手FIN报文,最大次数由tcp_orphan_retries决定;超过最大次数后再等待两倍时间就会断开

第二次挥手丢失了,发生什么?
重传第一次挥手FIN报文(ACK报文是不会重传的)
对于调用close关闭的连接,60秒内没有收到FIN报文,主动关闭方就会关闭连接

第三次挥手丢失了,发生什么?
和第一次挥手丢失后有些类似,重传并等待第四次挥手,超过参数后断开连接

第四次挥手丢失了,发生什么?
重传第三次挥手FIN报文。
客户端接收到 FIN 后发送 ACK ,进入TIME_WAIT状态并等待2MSL 的时间。如果在 2MSL 时间内,因为客户端的 ACK 没有传输到服务端,客户端又接收到了服务端重发的 FIN 报文,那么 2MSL 时间将重新计时。

为什么需要TIME_WAIT

  1. 2MSL的时间足以让原来连接的数据包都自然消失,防止历史连接数据被相同四元组错误连接接收
  2. 保证正确关闭。如果没有2MSL,客户端直接CLOSE,如果服务端再向已关闭的客户端发送FIN报文,客户端会回 RST 报文,不属于正常关闭了。
客户端TIME_WAIT过多服务端TIME_WAIT过多
危害占用端口资源,很难和目的IP + Port 一样的服务器建立连接,但只要是不同的服务器还是可以重复使用的因为服务器只监听一个端口,不会导致端口资源受限;但是会占用系统资源,比如fd、内存、CPU等
TCP客户端出现故障服务端出现故障
建立连接后socket设置SO_KEEPALIVE启动保活机制,定时检测客户端故障造成的死亡连接服务端会发送FIN和客户端进行挥手

3.2 TCP 重传、滑动窗口、流量控制、拥塞控制(可靠性传输)

重传机制

超时重传

数据包确认应答丢失的时候会触发重传
超时重传时间是以RTO(Retransmission Timeout 超时重传时间)表示,不应过大或过小,略大于RTT(往返时延)即可;同时它是动态变化的,比如说再次超时的时候时间间隔加倍。

缺点:超时周期相对长,需要快速重传。

快速重传

不以时间驱动,而是以数据驱动重传。
当收到三个相同的 ACK 报文时,会在定时器过期之前,重传丢失的报文段。
解决了超时时间问题,但不知道重传一个还是所有,比如,连续收到三个ack2,不能确定自己是seq2丢失还是seq2和3都丢失。
快速重传机制只解决了一个问题,就是超时时间的问题,但是它依然面临着另外一个问题。就是重传的时候,是重传一个,还是重传所有的问题。

SACK(选择性确认)

TCP头部选项字段里加入SACK

D-SACK

使用了 SACK 来告诉「发送方」有哪些数据被重复接收了。
主要场景:

  1. 网络延时,两次报文同时被接收,接收方提醒
  2. 之前发送成功后接收方返回的ACK报文丢包了,因此重发了一次

重传机制

方法超时重传快速重传SACKD-SACK
含义数据包或应答丢失时重传不以时间而是数据驱动将已收到的数据发送给”发送方“告诉”发送方“哪些数据被重复接收,笔面网络延迟 / 应答报文丢失 造成的重传
优点解决了超时问题可以只重传丢失的数据1.让发送方知道是数据包还是ACK丢了
2.知道是不是数据包网络延迟了
确定超时周期太长不知道该重传哪些

滑动窗口

可以批量发送若干报文,集中收到ack后再发送下一批次。
窗口大小由接收方窗口大小决定
发送方的窗口:SND.WND由接收方指定
在这里插入图片描述
发送方和接收方的窗口大小是约等于的,比方说接收方读取很快,新的接收窗口大小传输给发送方有时延

流量控制 (考虑对缓存的影响)

「发送方」根据「接收方」的实际接收能力控制发送的数据量(系统资源繁忙影响),避免「发送方」的数据填满「接收方」的缓存

方法:操作系统的缓冲区影响发送和接收窗口

  1. 系统内核缓冲区:存放发送和接收窗口的字节数,会被调整。具体的调整过程类似于:接收方因为资源繁忙,只读取了一部分字节,剩下n个字节占用着缓冲区,于是窗口缩小到size - n,并在发送确认信息时通知发送方也调整大小,接着发送方的窗口大小也缩小为size - n

  2. 如果通知没被发送方及时接收,那发送方可能会发送超过此时接收方窗口大小的数据,就会产生丢包
    采取的办法是:先收缩窗口,后减少缓存

  3. 窗口关闭的死锁:恢复窗口的通知如果丢失会进入死锁,解决方法是只要 TCP 连接一方收到对方的零窗口通知,就启动持续计时器。

  4. 对于窗口很小的情况,持续发送报文开销很大。解决办法为:
    接收方「不通告小窗口给发送方」+ 发送方开启 Nagle 算法 方能解决

拥塞控制 (考虑对网络的影响)

避免「发送方」的数据填满整个网络

发送窗口swnd由接收窗口决定
接收窗口rwnd约等于发送
拥塞窗口cwnd发送方维护,根据网络拥塞动态变化
发送窗口会等于min(cwnd,rwnd)

拥塞控制四大算法:

  1. 慢启动。建立连接后,发送方每收到一个ACK,cwnd的大小加1(窗口大小指数增加)
  2. 拥塞避免算法。cwnd >= ssthresh(slow start threshold)时启动。每收到一个ACK,cwnd增加1 / cwnd,(实际变成了线性增长)
  3. 拥塞发生算法。 当发送重传时的拥塞算法。
     当发生了「超时重传」:
       (1)thresh = cwnd/2
       (2)cwnd = 1
     当发生了「快速重传」:
       (1)thresh = cwnd/2
       (2)cwnd /= 2
  4. 快速恢复。 配合快速重传,拥塞发生造成cwnd减少后,快速回到一个稳定的线性增长水平,尽快将丢失的数据包发给目标

3.3 TCP 半连接队列和全连接队列(没看


3.4 如何优化 TCP

三次握手的性能提升

客户端:

  1. 调整SYN重传次数tcp_syn_retries,比如内网通讯时可以调低,把错误暴露给应用程序

服务端:

  1. 调整SYN+ACK重传次数tcp_synack_retries
  2. 调整队列长度。因为队列满了后可能会丢弃连接,但注意,半连接队列满了后未必会丢弃连接,开启syncookies可以不使用半连接队列而建立连接,tcp_abort_on_overflow设为1可以在全连接队列满了后给客户端返回RST报文,以明确成因,通常设为0
  3. 绕过三次握手。使用TFOTCP Fast Open,首次连接需要三次,但缓存了Cookie后,再次连接时服务器校验Cookie,如有效,可在握手前对应用程序发送数据,减少了1个RTT的消耗

四次挥手的性能提升

首先,关闭连接的方式有两种:
(1) RST报文关闭:暴力关闭,不可取
(2) FIN报文关闭:调用closeshutdown函数。调用close函数会完全断开,使用方叫做孤儿连接,进程名为空,不太行; shutdown可以只关闭读/写一个方向

主动方:

  1. 调整FIN重传次数(tcp_orphan_retries
  2. 调整孤儿连接(关闭方式为close函数)的上限,避免占用资源
  3. tcp_max_tw_buckets调整TIME_WAIT的最大数量
  4. tcp_tw_reuse新连接时直接复用TIME_WAIT状态的窗口

被动方:

  1. 调整FIN重传次数(同上)
  2. CLOSE_WAIT状态如果过多,需要排查应用程序bug,可能是因为read返回时没有调用close函数

数据传输的性能提升

TCP 连接是由内核维护的,内核会为每个连接建立内存缓冲区。

  • 如果连接的内存过小,就无法利用好网络带宽, 传输效率低;
  • 如果连接的内存过大,容易耗尽服务器资源,导致新连接无法建立;
  1. 扩大窗口大小
  2. 调整发送缓冲区:缓冲区最好和网络传输能力相匹配,受制于带宽(时延积);过高容易丢包,过低没法利用好网络效率
  3. 调整接收缓冲区:根据系统空闲内存来调节
  4. 总的来说缓冲区最大值到带宽时延积、最小4K即可;内存紧张时调低缓冲区可以提高并发
  5. tcp_mem调整TCP使用更多系统内存,提高并发能力

3.5 TCP连接一端断电 / 进程崩溃的区别

断电 / 进程崩溃

  • 如果进程崩溃内核接管:回收资源、发起四次挥手(即使没有keep alive)
  • 如果客户端断电 / 主机崩溃,且没有开启keepalive的话,服务端仍ESTABLISHED,直到服务端重启进程,具体得看服务器会不会再发送数据

数据传输时:

  • 客户端宕机又立即重启: 服务端超时重传,客户端重启接收后,回RST,重置连接。
  • 客户端宕机未重启: 服务器多次超时重传后断开

同样地,如果客户端断网

无数据传输:

如果没开启keepalive,连接一直存在;
开了keepalive,如果探测期间客户端恢复了网络,不影响TCP连接,要是一直不回复,2h+后会断开

传输数据:

超时重传到最大值前,恢复网络,则无事发生;
重传次数到最大值,服务端断开,客户端恢复后发给服务端数据,服务端会恢复RST,客户端再断开


3.5 TCP的缺点

  1. 建立连接的延迟。TLS 是在应用层实现的握手,而 TCP 是在内核实现的握手,总得先TCP后TLS(除非TLS1.3 + FastOpen + 第二次连接),增加延迟;同时TCP在内核,无法加密,容易伪造RST
  2. TCP队头阻塞。为了保证有序性,如果丢失了之后序列号会不匹配,只有等到重传后才能读取。 HTTP/2 队头阻塞问题就是因为 TCP 协议导致的
  3. 网络迁移(4G - WiFi)时要重新建立连接
  4. TCP基于内核实现,升级内核很难。

3.6 基于TCP的缺点,QUIC/UDP如何可靠传输

相同:

  1. 和TCP一样拥有的:流量控制拥塞控制

改善:

  1. 乱序确认。增加三个头部字段。支持乱序确认。解决了TCP必须按序传输
  2. 解决队头阻塞。每个字节流都是独立的滑动窗口,不影响其他
  3. 更快连接:QUIC和TLS都是应用层,不分层,QUIC内部包含了TLS,更快连接
  4. 迁移连接。QUIC没有四元组,而是连接ID,所以即使网络变化造成IP地址变化,也不影响

3.7 TCP会三次挥手吗?

为什么要四次?

接收方可能还有数据要发送,所以并不能马上发送 FIN 报文,而是将发送 FIN 报文的控制权交给接收方应用程序

什么情况下三次挥手?

1没有数据要发送2开启了TCP延迟确认机制

TCP延迟确认机制:解决了单独发送ACK(不带数据)效率低的问题

  • 有数据要发送时,ACK会一同发送
  • 没有数据要发送时,ACK会等待数据一起发送;如果这时又收到了数据报文,就会立刻发出

四、IP

4.1 IP基础

网络层数据链路层
八股为分组交换网上的不同主机提供通信服务在两个相邻节点间的链路上传送帧
区间「没有直连」的两个网络「直连」的两个设备
类比旅游行程表
行程表充当远程定位,起止点即IP地址
车票
飞机票和地铁票都只能在某一区间移动,起止点即MAC地址

旅行途中我们虽然不断变化了交通工具,但是旅行行程的起始地址和目的地址始终都没变;
源IP地址和目标IP地址在传输过程中是不会变化的(前提:没有使用 NAT 网络),只有源 MAC 地址和目标 MAC 一直在变化;

4.2 IP地址

IPv4点分十进制。依据不同网卡来配置; 前四位中直接看第几位是0就能分辨出是哪类IP地址

在这里插入图片描述

最大主机个数计算

最大主机个数要看主机号的位数,如C类地址主机号占8位,
最大主机个数:2^8 - 2 = 254(除去全1和全0,即广播和当前主机)

无分类地址CIDR

为了解决IP的缺点:

  1. 同一网络没有地址层次
  2. 有的分类下主机数量太少,而有的太多

CIDR无分类地址方案a.b.c.d/x。前x位网络号

在这里插入图片描述

子网掩码:
作用1:掩码的意思就是掩盖掉主机号,剩余的就是网络号。

  • 将子网掩码和 IP 地址按位计算 AND,就可得到网络号;子网掩码取反后相同操作,可得到主机号
  • 最大主机个数 == 可用地址个数 = 2^主机号位数 - 2
  • 广播地址 = 网络号 + 主机号全1

作用2:子网划分
划分后 IP地址 = 网络地址 + (子网网络地址 + 子网主机地址)

子网掩码转化为二进制后,对8取模多出的几位 对应着 子网网络地址
例如子网掩码255.255.255.192转化为二进制为:
11111111.11111111.11111111.11000000
    网络地址    子主机地址中借两位为子网网络地址

  • 子网网络地址:4个;其他的计算方式和作用一相同

公有IP地址和私有IP地址

  • 公有IP地址IANA组织管理;全世界都能访问,互联网内保持唯一
  • 私有IP地址:内部人员管理;可分配、可重复
公有IP地址私有IP地址
管理IANA组织管理内部人员管理
特点全世界都能访问,互联网内保持唯一可分配、可重复

IP地址与路由控制

在发送 IP 包时,首先确定目标地址,再从路由控制表中找到与该地址具有相同网络地址的记录,并转发给下一个路由器。如果路由控制表中存在多条相同网络地址的记录,就选择相同位数最多的网络地址,也就是最长匹配

IP分片与重组

  • 以太网的MTU1500字节,当IP数据包大于MTU时会被分片;
  • 只有到了目标主机才会被重组;
  • 因为一个分片丢失会造成整个IP数据报作废,所以TCP层引入MSS并进行分片,而不是由IP层分片;对于UDP,报文大小最好不要超过MTU

IPv6

特点及头部差异:

  1. IPv4是点分十进制32位,每8位一组;IPv6:分十六进制的128位,每16位一组
  2. 自动配置,没有DHCP也可以自动分配IP地址
  3. 包头包首部长度采用固定的值 40 字节,去掉了包头校验和,大大提高了传输性能
  4. 取消了分片和组装字段,不允许在中间路由器进行分片和组装;取消可选字段

4.3 IP协议

DNS (Domain Name System)域名解析

将域名网址转换为具体的IP地址

解析流程:
浏览器缓存 -> 操作系统缓存 -> hosts文件 -> DNF服务器


ARP(Address Resolution Protocol)地址解析协议

ARP

传输IP数据报时,通过主机的路由表确定IP数据包下一跳;ARP协议根据下一跳的IP地址求得下一跳的MAC地址
主要原理:广播ARP请求,包括了主机IP地址和想要知道的MAC地址;当设备检查自己的IP地址和目标IP地址一致时,就将自己的MAC地址返回给主机(也有缓存)

RARP

已知MAC地址求IP地址
例如,将打印机等小型嵌入式设备接入到网络时


DHCP (Dynamic Host Configuration Protocol)动态主机配置协议

电脑动态获取IP地址,省去了配IP的繁琐过程
客户端(监听68)对服务器(监听67)发起DHCP发现报文,DHCP服务器返回响应报文,携带可租的IP地址和租用期等;客户端从中选择一个并发送DHCP请求报文,服务端响应后交互完成。DHCP全程使用UDP广播进行通信


NAT (Network Address Translation)网络地址转换

网络地址转换方法,解决IPv4地址短缺问题
此前,通过无分类地址缓解IPv4地址短缺,此外还有NAT网络地址与端口转换;具体原理:NAPT路由器转换表将两个私有地址(不同)转换为同一个共有地址,但以不同端口号区分
缺点:

  1. NAPT转换表无记录
  2. 转换产生开销
  3. NAT路由器重启后TCP连接将被重置

解决:

  1. IPv6
  2. NAT穿透:客户端主动获取公有IP地址,自己建立映射对外通信

ICMP (Internet Control Message Protocol)互联网控制报文协议

确认 IP 包是否成功送达目标地址、报告 IP 包被废弃原因、改善网络设置等。如果某个IP包未能送达目标地址,那么由ICMP负责通知,主要类型有查询报文类型(查询消息)和差错报文类型(通知出错消息)

IGMP (Internet Group Management Protocol)因特网组管理协议

管理组内成员
主机通过IGMP加入组播组,路由器记录IGMP路由器表,后续发送组播到对应主机;
IGMP报文用IP封装,头部协议号为2,TTL通常为1,因为IGMP工作在主机和路由器之间
PS:是否加入组播组和离开组播组,是由socket一个接口实现的,主机ip是不用改变的

  • 2
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值