【java入门到放弃】计算机网络

网络分层

OSI 七层模型:物理层、链路层、网络层、传输层、会话层、表示层、应用层

TCP/IP 四层模型:链路层、网络层、传输层、应用层

七层是理论模型,四层是实际实现。

层 英文 对应OSI层 主要协议 功能
应用层 Application 7、6、5(应用、表示、会话) HTTP, HTTPS, FTP, DNS, SMTP, POP3 为应用程序提供网络服务,定义数据格式和通信规则
传输层 Transport 4(传输层) TCP, UDP 提供端到端的数据传输,TCP可靠传输,UDP不可靠但快速
网络层 Internet 3(网络层) IP, ICMP, ARP 负责路由和寻址,把数据包从源发送到目的地
链路层 Network Interface / Link 2、1(数据链路 + 物理层) Ethernet, WiFi, PPP 负责局域网内的比特传输,把数据封装成帧

TCP/IP 不是单一协议,而是一整套协议的统称,是一个协议族。

TCP协议是解决传输,IP协议是解决互联。

了接链路层

最核心的协议就是 Ethernet(以太网)。

帧(MAC 帧 / 以太网帧)

shell 复制代码
#Ethernet 的核心:帧(Frame)
[目标MAC][源MAC][类型][数据][CRC校验]
#类型(Type)
0x0800 → IP协议
0x0806 → ARP协议
#数据(Payload)
IP包
#CRC(校验)
检测数据是否损坏

ARP 表

ARP 全称是:Address Resolution Protocol(地址解析协议)

ARP 表就是一个 缓存表,记录了 IP 和 MAC 的对应关系。

特点:

  • 动态更新:主机访问新的 IP 时,会自动通过 ARP 获取 MAC 并加入表中
  • 缓存:ARP 表防止每次发数据都重新广播查询,提高效率

只记录局域网的。

广播使用到的协议:http、ip、ARP

举例

局域网通信

  1. A 要发数据给 B
  2. 先看 ARP 表有没有 B 的 MAC
  3. 如果没有 → 发 广播 ARP:谁是 192.168.1.20?请告诉我你的MAC
  4. B 回复:我是192.168.1.20,MAC=BB:BB:BB:BB:BB:BB
  5. A 封装 Ethernet 帧:源MAC:AA:AA:AA:AA:AA:AA、目标MAC:BB:BB:BB:BB:BB:BB
  6. 交换机转发,B 收到帧,去掉链路层头,处理 IP/TCP/HTTP。

跨网段通信

假设 A 想访问公网:

电脑A: 192.168.1.10, MAC=AA:AA:AA:AA:AA:AA

路由器内网口: 192.168.1.1, MAC=RR:RR:RR:RR:RR:RR

  1. A 发数据到 8.8.8.8(外网)
  2. 因为不在同一网段 → 发给网关(路由器)
  3. A 的 ARP 查询网关 MAC:谁是 192.168.1.1?请告诉我你的 MAC
  4. 路由器回复:我是192.168.1.1, MAC=RR:RR:RR:RR:RR:RR
  5. A 封装帧:源MAC:AA:AA:AA:AA:AA:AA 目标MAC:RR:RR:RR:RR:RR:RR
  6. 路由器收到帧 → 去掉链路层头 → 转发 IP 包 → 封装新的链路层帧给下一个设备(运营商设备 MAC)

源 IP / 目标 IP:端到端不变,记录在 IP 包头

下一跳 IP / MAC:逐跳变化,由路由器决定,不记录在 IP 包里

下一跳 IP 是什么,学IP协议时再了解

IP协议

IP数据包

IP 协议传输的数据格式叫 IP 数据包(IP Packet)。

由 报头(Header) + 数据部分(Payload) 组成,报头用来指示路由、目的地和控制信息,数据部分承载上层协议(TCP/UDP/ICMP)数据。

有 最大传输单元(MTU)限制,数据包不能超过链路层允许的大小;IPv4 可由路由器分片,IPv6 只由源主机分片。

是 无连接协议,不保证数据包到达顺序,也不保证丢包重传,可靠性由 TCP 或上层应用保证。

有 生存时间字段:IPv4 的 TTL,IPv6 的 Hop Limit,用于防止数据包在网络中无限循环。

前置知识:NAT

NAT(Network Address Translation,网络地址转换)是一个在路由器或防火墙上进行 IP 地址转换的技术,本质作用是:让局域网里的多台设备通过一个公网 IP 上网,同时隐藏内部网络结构,提高安全性。

发消息举例

  1. 客户端发起连接:192.168.1.10:52341 → 8.8.8.8:80

  2. NAT 转换:1.2.3.4:10001 → 8.8.8.8:80

  3. 服务器看到:1.2.3.4:10001

  4. 服务器返回:→ 1.2.3.4:10001

  5. 路由器查 NAT 表: 10001 → 192.168.1.10

  6. 转发给客户端

NAT 只改 IP

NAPT 改 IP + 端口

当内网设备通过 NAT 出公网时:

源 IP 会被修改为公网 IP,TCP/UDP 的源端口通常也会被重新分配(端口映射),而目标 IP 和目标端口保持不变。

当外部数据通过 NAT 进入内网时:

目的 IP 会被修改为内网设备的 IP,TCP/UDP 的目标端口根据 NAT 映射规则进行转换,而源 IP 和源端口保持不变。

其中,IP 地址记录在 IP 数据包头部,端口号记录在 TCP 或 UDP 头部。

路由表

路由表的作用:决定数据包"下一跳发给谁"

由上一节可知,,源ip和目标ip都会变。

更新方式:

  • 静态路由:管理员配置

  • 动态路由:路由协议自动更新(RIP/OSPF/BGP)

先查路由表找最匹配的路,由路由表告诉你下一跳是谁,局域网内就直接发给设备,否则发给网关。

与下层交互

IP协议去Ethernet协议:太大了就分片,网络层封装ip报头,数据链路层封装mac帧报头。

Ethernet协议去IP协议:数据链路层去掉mac帧报头,网络层去掉ip报头,之前有分片就需要组装。

TCP协议

TCP全称"传输控制协议"(Transmission Control Protocol),是如今互联网应用最为广泛的传输层协议

报头格式

TCP报头中的6位标志位:

标志位 缩写 含义 / 功能
URG Urgent 紧急指针是否有效,指示有紧急数据
ACK Acknowledgment 确认号是否有效,表示这是确认报文
PSH Push 提示接收端应用立即读数据,不用缓冲太久
RST Reset 重置连接,请求对方重新建立连接
SYN Synchronize 请求建立连接(同步序号)
FIN Finish 通知本端要关闭连接

TCP状态机

TCP 状态机(TCP State Machine)

属于 TCP 协议规范的一部分

1️⃣ LISTEN(服务端)

  • 服务器在监听端口
  • 等待客户端连接

2️⃣ SYN-SENT(客户端)

  • 客户端发出 SYN
  • 等待服务器回应

3️⃣ SYN-RECEIVED(服务端)

  • 收到 SYN
  • 回复 SYN+ACK
  • 等待客户端 ACK

4️⃣ ESTABLISHED(双方)

  • 连接建立成功 ✅
  • 可以正常收发数据

5️⃣ FIN-WAIT-1(主动关闭方)

  • 发出 FIN(我要断开)

6️⃣ FIN-WAIT-2

  • 对方已经 ACK
  • 等待对方的 FIN

7️⃣ CLOSE-WAIT(被动关闭方)

  • 收到 FIN
  • 等待应用层决定什么时候关闭

8️⃣ LAST-ACK

  • 被动方发出 FIN
  • 等待最后 ACK

9️⃣ TIME-WAIT(主动关闭方)

  • 等待一段时间(2MSL)
  • 确保对方收到 ACK

🔟 CLOSED

  • 完全关闭

缓冲区

TCP存在接收缓冲区和发送缓冲区

TCP报头中就有了16位窗口大小,这个16位窗口大小中填的是自身接收缓冲区中剩余空间的大小,即当前主机接收数据的能力

接收端在对发送端发来的数据进行响应时,就可以通过16位窗口大小告知发送端自己当前接收缓冲区剩余空间的大小,此时发送端就可以根据这个窗口大小字段来调整自己发送数据的速度

确认应答机制

确认应答机制就是由TCP报头中的32位序号和32位确认序号来保证的。确认应答机制不是保证双方通信的全部消息的可靠性,而是通过收到对方的应答消息,来保证曾经发送给对方的某些消息被对方可靠的收到了

序号(Sequence Number):

表示"本报文段第一个字节"的编号

确认序号(Acknowledgment Number):

表示"期望收到的下一个字节编号"

只要 ACK=1,确认序号(Acknowledgment Number)才有意义

三次握手

第一次 客户端发送 SYN 报文(带初始序号 x),表示请求建立连接;
第二次 服务端收到后回复 SYN+ACK(确认 x+1,并发送自己的初始序号 y),表示同意连接并告知自己的序号;
第三次客户端再发送 ACK(确认 y+1),表示已收到服务端信息,至此双方确认彼此收发能力正常,连接建立完成。

四次挥手

第一次 主动关闭方发送 FIN(SEQ=x),表示"我这边数据发完了";
第二次 被动方回复 ACK(ACK=x+1),表示"我知道你要关闭了";
第三次 被动方在数据发送完后再发送 FIN(SEQ=y),表示"我这边也发完了";
第四次主动方回复 ACK(ACK=y+1),表示"确认关闭",随后进入 TIME-WAIT,最终双方连接彻底关闭。

为什么不三次挥手

服务器收到客户端的 FIN 报文时,内核会马上回一个 ACK 应答报文,但是服务端应用程序可能还有数据要发送,所以并不能马上发送 FIN 报文,而是将发送 FIN 报文的控制权交给服务端应用程序:

如果服务端应用程序有数据要发送的话,就发完数据后,才调用关闭连接的函数;

如果服务端应用程序没有数据要发送的话,可以直接调用关闭连接的函数,

从上面过程可知,是否要发送第三次挥手的控制权不在内核,而是在被动关闭方(上图的服务端)的应用程序,因为应用程序可能还有数据要发送,由应用程序决定什么时候调用关闭连接的函数,当调用了关闭连接的函数,内核就会发送 FIN 报文了,所以服务端的 ACK 和 FIN 一般都会分开发送。

与下层交互

TCP 把应用数据封装成报文段交给 IP,IP 封装成 IP 包发送;接收端 IP 分片重组后交给 TCP,TCP 通过序号/确认号保证可靠、按序交付应用。

HTTP协议

HTTP(Hyper Text Transfer Protocol)协议又被称为做超文本传输协议,是一种简单的请求-响应协议,HTTP通常运行在TCP之上

版本

1️⃣ HTTP/0.9

  • 发布时间:1991 年
  • 特点:
    • 只有 GET 方法
    • 没有 HTTP 头
    • 只支持纯文本
  • 使用场景:非常早期的网页浏览

2️⃣ HTTP/1.0

  • 发布时间:1996 年,RFC 1945
  • 特点:
    • 支持多种方法:GET、POST、HEAD
    • 每次请求默认短连接
    • 引入 HTTP 头(Header)
  • 影响:初步支持状态信息和内容类型

3️⃣ HTTP/1.1

  • 发布时间:1997 年,RFC 2068(后更新为 RFC 2616)
  • 特点:
    • 默认长连接(Persistent Connection)
    • 支持管线化(Pipeline)请求
    • 增强缓存、分块传输(Chunked Transfer)
    • 更多 HTTP 方法:PUT、DELETE、OPTIONS 等
  • 影响:几乎成为互联网主流 HTTP 协议

4️⃣ HTTP/2

  • 发布时间:2015 年,RFC 7540
  • 特点:
    • 二进制协议(而非文本协议)
    • 多路复用(一个 TCP 连接可并行多个请求/响应)
    • 头部压缩(HPACK)
    • 优化性能,减少延迟
  • 影响:提高网页加载速度,兼容 HTTP/1.1

5️⃣ HTTP/3

  • 发布时间:2022 年,RFC 9114
  • 特点:
    • 基于 QUIC 协议(UDP)
    • 内置多路复用,解决 TCP HOL 阻塞
    • 0-RTT 快速连接
  • 影响:进一步降低延迟,适合移动网络环境

大部分新 Spring Boot 项目:

  • 默认 HTTP/1.1
  • 简单、兼容性好、易部署
  • 适合小型或内部系统,不需要额外配置

请求的结构

HTTP 请求一般分为 三部分:

  1. 请求行(Request Line)
  2. 请求头(Headers)
  3. 请求体(Body,可选)

1️⃣ 请求行(Request Line)

格式:

复制代码
METHOD SP URL SP HTTP/VERSION CRLF
  • METHOD :请求方法,例如 GET, POST, PUT, DELETE
  • URL:请求路径(可以带查询参数)
  • HTTP/VERSION :HTTP 版本,例如 HTTP/1.1
  • CRLF :回车换行(\r\n)

示例:

复制代码
GET /index.html HTTP/1.1

2️⃣ 请求头(Headers)

  • 每行一个字段,格式:Header-Name: Header-Value
  • 用于传递客户端信息、Cookie、缓存策略、内容类型等
  • 多个头部连续写,每行结尾都是 CRLF
  • 结尾用一个空行 CRLF 表示请求头结束

示例:

HTTP/1.1 请求头中必须有 Host,其它标准头如 Content-Type/Accept 可选;Key 可以自定义,现代做法不一定加 X- 前缀,但要避免与标准头冲突。

复制代码
Host: www.example.com
User-Agent: Mozilla/5.0
Accept: text/html

3️⃣ 请求体(Body,可选)

  • 仅在某些方法中使用 ,如 POST, PUT
  • 包含发送给服务器的数据,例如表单、JSON、二进制文件
  • 请求体与请求头之间必须有一个空行(CRLF)隔开

示例(POST JSON):

复制代码
POST /api/login HTTP/1.1
Host: www.example.com
Content-Type: application/json
Content-Length: 48

{"username":"alice","password":"123456"}

响应的结构


一、HTTP 响应的基本结构

复制代码
状态行 (Status Line)
响应头 (Headers)
空行
响应体 (Body,可选)

二、详细说明

1️⃣ 状态行(Status Line)

格式:

复制代码
HTTP/VERSION STATUS_CODE REASON_PHRASE\r\n
  • HTTP/VERSION :协议版本,例如 HTTP/1.1

  • STATUS_CODE

    :状态码,三位数字,例如:

    • 2xx 成功(200 OK)
    • 3xx 重定向(301 Moved Permanently)
    • 4xx 客户端错误(404 Not Found)
    • 5xx 服务器错误(500 Internal Server Error)
  • REASON_PHRASE:状态描述,可选,不影响客户端处理

示例:

复制代码
HTTP/1.1 200 OK

2️⃣ 响应头(Headers)

  • 每行一个字段,格式:Header-Name: Header-Value
  • 传递元信息,例如内容类型、长度、缓存策略、服务器信息等
  • 常见头部:
头部名 作用
Content-Type 响应内容类型,如 text/html 或 application/json
Content-Length 响应体长度(字节数)
Server 服务器类型,如 Apache 或 nginx
Set-Cookie 设置 cookie 给客户端
Cache-Control 缓存策略
  • 结尾必须有空行 CRLF,表示响应头结束

示例:

复制代码
Content-Type: application/json
Content-Length: 48
Server: SpringBoot

3️⃣ 响应体(Body,可选)

  • 存放实际返回的数据(HTML 页面、JSON、图片等)

  • GET/POST 都可能有响应体

  • 例如返回 JSON:

    {
    "username": "alice",
    "status": "ok"
    }

HTTPS协议

加密方式

服务器给客户端传非对称加密传公钥,客户端使用公钥加密之后对称加密的密钥,然后传给服务器,如此一来,服务器和客户端就都有了对称加密的密钥。

TLS 证书

一个典型的 TLS 证书包含:

1️⃣ 基本信息

  • 域名(如:www.example.com)
  • 组织信息
  • 有效期(起止时间)

2️⃣ 公钥(最重要)

  • 服务器的公钥(RSA 或 ECC)

👉 注意:
私钥只在服务器本地,永远不会传输

3️⃣ 签发者(Issuer)

  • 谁签发的(CA)

4️⃣ 数字签名(核心🔥)

CA 用自己的私钥,对证书内容做签名

注意点

证书里的公钥是明文的(不加密),核心安全点不在"保密",而在"防篡改"

数字签名 = 私钥签名,公钥验证

浏览器(或操作系统)内置了一批"受信任的 CA 公钥"

相关推荐
代码方舟7 分钟前
零信任架构实战:基于天远人企关联构建自动化供应链核心企业关联穿透与利益冲突审查网关
java·人工智能·架构·自动化
多弗朗皮卡丘37 分钟前
C++的IO流
开发语言·c++·io流·文件io流
liyi_hz20081 小时前
O2OA(翱途) V10.1 即将发布|功能再升级,安全再加固,协同更高效!
java·javascript·windows·开源软件
骑着蜗牛撵大象3271 小时前
AI Agent 工程化开发实战(三):用 StateGraph 给智能体搭一条可回放的状态流水线
java·开发语言·jvm·ai·状态管理·langgraph·stategraph
itmigrate1 小时前
Rust 里的所有权误区:不是不写 clone 就叫高性能
开发语言·后端·rust
Brilliantwxx1 小时前
【Linux】 文件访问与路径解析:目录、文件名、dentry、路径缓冲与 dcache 全解析
linux·运维·服务器·开发语言·spring
鬼手点金1 小时前
KV Cache 未必是一次性的:可编辑、可组合的“笔记”
java·人工智能·笔记·学习·自动化·1024程序员节
摇滚侠1 小时前
《On Java 中文版 基础卷》阅读笔记 初始化和清理 08
java·开发语言·笔记
xiangyun612 小时前
C++ 手撕 shared_ptr:引用计数与控制块到底长什么样?
开发语言·c++·算法·面试·stl
海鸥-w2 小时前
Redis 配置与排错说明
java·数据库·redis·bootstrap