从零开始 · 由浅入深

本地开发服务, 端口与网络访问基础

从浏览器输入地址到看到页面的完整链路。每一层概念都在它第一次被用到的场景中解释, 不跳步, 不假设你已经知道。

0

从一个具体场景开始

你做了什么

终端里运行 php artisan serve --port=8120npm run dev,然后浏览器输入 http://localhost:8120,页面出现了。

本文的目标

把这"一瞬间"拆开——从你敲下回车到看到页面的每一步,让你以后遇到端口不通、样式丢失、WSL2 连不上等问题时,能自己判断问题出在哪一层。

1

浏览器如何找到你的服务——URL 到连接

URL 输入http://localhost:8120 解析主机名hosts 文件 → 127.0.0.1 TCP 连接三次握手到 :8120 HTTP 响应页面出现! localhost 不需要联网解析——hosts 文件里写了 127.0.0.1 localhost,操作系统直接返回⚠️ 如果 hosts 中 ::1 (IPv6) 排在前面,且服务只监听 IPv4,可能出现"解析成功但连不上"

URL 三要素

http(协议)说用什么语言交谈;localhost(主机名)说去哪台机器;8120(端口)说进哪个门。

默认端口

http:// 默认 80,https:// 默认 443。不写端口时浏览器自动补上。

三次握手

浏览器说"在吗?"→ 服务器说"在"→ 浏览器说"好,开始传"。连接建立后发 HTTP 请求。

2

端口——一台机器上的服务门牌号

为什么需要端口

一台电脑可以同时运行 MySQL (3306)、Redis (6379)、Laravel (8120,本文示例)、Vite (5173)。IP 找到机器,端口找到服务。类比:IP = 写字楼地址,端口 = 房间号。

一个连接需要两个端口

源端口(操作系统随机分配)+ 目标端口(服务监听的)。多个浏览器标签可以同时访问同一服务——每个标签的源端口不同。

端口范围名称说明举例
0 - 1023知名端口系统保留,绑定需管理员80 (HTTP), 443 (HTTPS), 22 (SSH)
1024 - 49151注册端口应用常用,无需管理员3306 (MySQL), 6379 (Redis), 3000/5173 (开发)
49152 - 65535动态/私有系统临时分配浏览器发起连接时的源端口
3

服务是什么——进程、监听与生命周期

程序 vs 进程

程序是磁盘上的文件(如 php.exe),进程是加载到内存中运行起来的实例。食谱 vs 厨师炒菜。

"监听"的意思

进程调用 bind() 告诉操作系统:"我要在 127.0.0.1:8120 等连接"。此后操作系统代为处理 TCP 握手,把连接交给进程。

端口冲突

同一个端口同一时间只能被一个进程监听。启动第二个会报 EADDRINUSE。终端关了,服务就没了。

查看谁在监听:Linux/WSL → ss -ltnp | grep 8120;Windows → Get-NetTCPConnection -LocalPort 8120
4

IP 地址全览——从 127.0.0.1 到公网

127.0.0.1——回环接口

操作系统内核中的虚拟接口(Linux: lo,Windows: Loopback Pseudo)。数据包进入后立即返回,从不经过物理网卡。整个 127.x.x.x 网段都是回环地址。

0.0.0.0——通配绑定

只能在服务启动时作为监听地址使用,意思是"在所有网卡上监听"。不能作为浏览器访问地址——输入 http://0.0.0.0:8120 不会工作。

地址含义浏览器能访问?
127.0.0.1当前设备的回环地址✅ 访问本机服务
localhost主机名,解析到 127.0.0.1 或 ::1✅ 同上
0.0.0.0绑定所有网卡(仅监听用)❌ 不是访问地址
192.168.x.x / 10.x.x.x / 172.16-31.x.x私有地址,局域网内使用✅ 局域网内可访问
5

监听地址决定"谁能敲门"

监听方式命令示例谁可以访问
127.0.0.1--host=127.0.0.1只有本机
localhost--host localhost解析到 127.0.0.1 或 ::1
0.0.0.0--host=0.0.0.0本机、局域网、WSL2、Docker 全能
局域网 IP--host 192.168.1.100只有通过这个 IP 来的请求
建议:纯本地开发 → 127.0.0.1;需手机/同事测试 → 0.0.0.0;WSL2 开发 → 0.0.0.0(兼容性最好);数据库仅本地 → 127.0.0.1(安全优先)。
6

一个页面不只是一个请求

浏览器 📄 HTML 后端服务 (8120) 🎨 CSS / JS 前端服务 (5173) 🖼 图片 / 字体 / API 后端或静态服务 ✅ 页面能打开 ≠ 一切正常 ❌ 样式/JS 失败 → 查前端资源链路 端口?URL?HMR?转发? API / 图片 / 字体 失败 查路径、CORS、权限 HTML 返回成功 只是第一步
排查时打开 Network 面板(F12),看 Name、Status、Type 三列。Status 是 (failed) → 先查连通;Status 404/500 → 查服务端;Status 200 但样式不对 → 可能缓存,勾选 Disable cache。
7

多服务开发环境——Laravel + Vite 为什么有两个服务器

传统 vs 现代

传统:一个后端服务返回一切。
现代:后端返回 HTML + API,前端开发服务器返回 CSS/JS(支持 HMR 热更新)。

HMR 是什么

Hot Module Replacement:修改代码后浏览器自动更新,不刷新整个页面。Vite 通过 WebSocket(ws://localhost:5173)通知浏览器。WSL2 场景下 HMR 连接也可能受转发影响。

concurrently:concurrently 一个命令同时启动 Laravel + Vite,Ctrl+C 一起关闭。不用开两个终端。
8

网络边界——每个环境有自己的 127.0.0.1

WSL2 是什么

不是一个简单模拟器,而是一个完整的 Linux 内核运行在 Hyper-V 虚拟机中。拥有独立的网络命名空间、独立的 IP 地址。

Docker 叠加

Docker Desktop + WSL2 后端 → 每个容器还有自己的网络命名空间。形成 Windows → WSL2 → Docker 三层"套娃"。

关键认知

Windows、WSL2、Docker 各有独立的回环接口(lo)和独立的 127.0.0.1。它们天然隔离、互不干扰。

核心问题:如果三个 127.0.0.1 彼此隔离,那为什么 Windows 浏览器访问 localhost:8120 能到达 WSL2 里的服务?
→ 答案:WSL2 内置了 wslhost.exe 自动转发机制。
9

WSL2 网络深入——打破隔离的转发机制

Chromeconnect(127.0.0.1:3000) TCP/IP 栈127.0.0.1 → 回环接口 🔑 wslhost.exe已接管 127.0.0.1:3000封装 → VMBus Windows 主机 VMBus 通道Hyper-V 内部通信, 不走物理网卡 WSL2 relayinit 进程内中继 Node/Python/PHPWSL2 内 127.0.0.1:3000 WSL2 VM 工作原理 1. WSL2 服务监听端口 2. relay 检测到,通知 wslhost 3. wslhost 在 Windows 侧创建监听 4. Windows 请求 → wslhost → VMBus → relay → 服务 对浏览器和应用完全透明 ⚠ 转发失效常见原因 休眠/快速启动 → wsl --shutdown Windows 端口保留 → 换端口 VPN 路由干扰 → 排查 VPN 防火墙拦截 → 添加规则 最高频修复: wsl --shutdown 不需要重启 Windows!
一句话答案:Windows 的 127.0.0.1 和 WSL2 的 127.0.0.1 确实不同——它们属于两个独立的网络命名空间。但 WSL2 内置的 wslhost.exe 充当了"接线员":它在 Windows 侧监听端口,通过 Hyper-V 的 VMBus 通道把流量隧道转发到 WSL2。整个过程对浏览器和应用完全透明。

NAT 模式(默认)

WSL2 有独立 IP (172.x.x.x),通过 Hyper-V NAT 上网。localhost 转发由 wslhost 实现。所有版本都支持。

Mirrored 模式

Win11 22H2+。WSL2 与 Windows 共享 IP。通过 loopback0 接口中继。IPv6 和 VPN 兼容性更好。在 .wslconfig 中设置 networkingMode=mirrored

10

端口冲突跨环境——Windows 端口被占, WSL2 还能用吗

WSL2 内可用 ✅

Windows 和 WSL2 是独立的网络命名空间,端口资源不共享。Windows 的 6543 被占用,完全不影响 WSL2 内使用 6543。

Windows 访问有问题 ⚠️

wslhost.exe 需要在 Windows 的 127.0.0.1:6543 创建监听做转发。如果这个端口已被占用,wslhost 无法绑定 → 转发失败。但 WSL2 内部完全不受影响。

解决方案:(1) 换端口(WSL2 服务用 Windows 空闲的端口);(2) 用 WSL2 IP 直连(wsl hostname -I 获取 IP,浏览器访问 http://172.x.x.x:端口,前提是服务监听 0.0.0.0)。
11

WSL2 中监听 127.0.0.1 vs 0.0.0.0 的差异

监听地址WSL2 内 curlWindows localhostWSL2 IP 直连局域网
127.0.0.1⚠️ 仅依赖 wslhost
0.0.0.0✅ 转发 + IP 直连✅ 需防火墙

为什么 0.0.0.0 多一条路

路径A: wslhost 转发(依赖 WSL2 自动机制)
路径B: WSL2 IP 直连(不依赖 wslhost)
即使转发因休眠失效,路径B仍然可用。

⚠ 安全提醒

在 WSL2 中监听 127.0.0.1 不意味着"对 Windows 不可见"——wslhost 仍然会把它转发到 Windows。这是 WSL2 的设计特性,不是安全边界。

12

端口故障——四类问题和排查顺序

类型本质表现第一验证
进程没启动没有人在等Connection refused终端有无报错
监听地址不对没在门口等WSL 内通,Windows 不通确认 --host 参数
端口被占用门牌号已被用EADDRINUSEss -ltnp
端口被系统保留管理层禁止无明显占用但不能绑netsh excludedportrange
排查口诀(从近到远):Network 面板确认失败请求 → 确认进程在运行 → 服务环境内 curl → 浏览器环境测端口 → 跨环境查转发 → CORS(最后才查)。不要跳步!
13

CORS——浏览器安全策略入门

什么是 CORS

浏览器安全策略。网页向不同"源"(协议+主机+端口)发请求时,浏览器检查对方是否允许。源的三要素中任何一个不同,就是跨源。

别一上来就查 CORS

端口都不通 → 先修端口,不是 CORS。
Status (failed) → 连接失败,不是 CORS。
HTTP 200 但被浏览器拦截 → 这才是 CORS。
开发中最简单的解决:前端 dev server 代理 API。

14

实战场景速查

场景① 页面能打开没样式

HTML 返回成功 → 查 CSS/JS。Network 面板 filter: stylesheet,看 Request URL 的端口是否正确。确认前端服务是否在运行。

场景② WSL 内 curl 通, Windows 不通

服务正常,转发问题。wsl --shutdown → 重开 WSL → 重启服务。还不通就检查 Windows 端口保留。

场景③ 端口自动变了

原端口被占用,服务悄悄换到下一个。使用 --strictPort 让它在端口不对时报错而非悄悄成功。

场景④ WSL2 休眠后不通

最常见的"玄学"问题。根因:Hyper-V 网络未恢复。验证:wsl curl -I http://127.0.0.1:端口 成功 + Test-NetConnection 失败。解决:wsl --shutdown

15

命令速查

Linux / WSL

ss -ltnp
curl -I http://127.0.0.1:端口
lsof -i :端口
hostname -I
wsl --shutdown

Windows PowerShell

Test-NetConnection 127.0.0.1 -Port 端口
Get-NetTCPConnection -LocalPort 端口
netsh int ipv4 show excludedportrange protocol=tcp
wsl --shutdown
wsl hostname -I
学习阶段要掌握的问题推荐搜索词
基础进程、端口、监听是什么意思what does listen on a port mean
地址127.0.0.1 / localhost / 0.0.0.0 区别127.0.0.1 vs 0.0.0.0 explained
回环接口lo 接口本质, 不同环境的 127loopback interface network namespace
WSL2 网络Windows 和 WSL2 互访、转发机制WSL2 localhost forwarding
wslhostwslhost.exe 如何实现端口转发wslhost.exe VMBus Hyper-V socket
前端开发Vite HMR、WebSocket、资源 URLVite dev server HMR WebSocket
浏览器安全CORS 按 origin 判断CORS origin protocol host port
16

总结——你应该带走的十点认知

  1. 服务是一个正在运行的进程,进程必须监听某个地址和端口才能被访问。
  2. 127.0.0.1 是回环地址,数据不经过物理网卡。每个网络命名空间有独立的 lo 接口——Windows、WSL2、Docker 的 127.0.0.1 彼此隔离。
  3. 端口是进程的"门牌号"。一个端口同一时间只能被一个进程监听。端口共 65535 个。
  4. 0.0.0.0 是监听地址(在所有网卡上监听),不是浏览器访问地址。
  5. 一个页面由多个请求组成——HTML 成功 ≠ CSS/JS/API 成功。排查时先看 Network 面板。
  6. WSL2 的 localhost 转发由 wslhost.exe + VMBus 实现——它是 Windows 访问 WSL2 服务的"地下通道"。
  7. wsl --shutdown 是修复 WSL2 网络问题的最高频命令,不需要重启 Windows。
  8. Windows 和 WSL2 端口资源独立。Windows 端口被占用时 WSL2 同名端口仍可用,但 wslhost 转发会失败。
  9. WSL2 中监听 0.0.0.0127.0.0.1 多一条备用访问路径(IP 直连)。
  10. 排查顺序:Network 面板 → 进程状态 → 服务内部 curl → 浏览器侧连通 → 转发/端口保留 → CORS。不要跳步。