故障排查 FAQ
连接类问题
访客提示 room not found or expired: xxx
- 房间号输入有误(区分大小写)
- 房间已过期(默认 12 小时)或被房主 Ctrl-C 关闭
- 让房主重新
game create获取新房间号
访客提示 UDP echo timed out
客户端无法与服务器的 UDP 探测端口通信:
- 检查服务器
8080/udp是否放行(云安全组 + 系统防火墙都要) - 检查配置
signaling_addr是否指向正确服务器 - 用
nc -u 服务器IP 8080或任意 UDP 客户端发ECHO test验证回显
一直 UDP hole punching failed, falling back to relay ...
打洞可能受 NAT 或防火墙影响。失败后可尝试 TURN 再回退 TCP;--relay 明确强制 TCP。中继延迟和吞吐取决于服务器线路与可用带宽,不能保证不影响使用。
--punch-retries 3:失败 3 轮后才降级(默认 1);--punch-retries 0完全跳过打洞- 尝试增大
--spread(对称 NAT 场景) - 双方都保证 UDP 出站可用;同一 WiFi 下看局域网直连
- 若两端在同一局域网/同一 NAT 后,公网打洞属 hairpin 场景,直连可能失败——保持降级走中继即可,或先试局域网直连路径(自动通告 LAN 地址)
- 达到打洞重试次数不等于禁用 TURN;显式
--relay才强制 TCP。
双方直连成功但数据不通(客户端连不上/连上没响应)
- 确认房主
--service指向的服务正在运行且监听正确端口 - 确认访客
--listen端口未被占用 - 用
--verbose查看帧日志是否在收发
decryption failed (wrong --key?)
双方 --key 口令不一致(或有一方没带)。统一口令后重开房间。
部署类问题
服务器启动报端口占用
AddrInUse8080或8081被其他进程占用,换端口:bashfrp-sh serve --addr 0.0.0.0:9000 --relay-addr 0.0.0.0:9001 --password "$FRPSH_SERVE_PASSWORD"- 客户端配置相应改为
http://IP:9000与IP:9001
Windows 上快速重启服务器报「权限不允许的套接字尝试」
Windows 下刚关闭的 TCP 监听端口会短暂处于过渡态,立即用同端口绑定 UDP 可能失败:
- 等待 2~3 秒再启动
- 或让 UDP 探测使用独立端口(
signaling_udp+ 服务器独立监听)
性能与稳定性问题
传输慢
- 可靠流窗口为 32 帧 × 1200B ≈ 38KB 在途;高延迟链路吞吐有限
- 若经中继,带宽受服务器出口限制
- 打洞直连一般比中继快(少一跳服务器)
长空闲后连接失效
NAT 映射有超时(通常 30~120s)。frp-sh 每秒互发 keepalive ACK 帧保活,正常不会失效;若你的 NAT 超时极短,可保持低频数据流动。
大流量时读缓冲丢弃帧
读缓冲上限 1MB,超过后丢弃帧并依赖重传(go-back-N 流控),属预期行为,不影响正确性。
安全类问题
中继模式数据安全吗?
分两层:
- 服务器设了密码(
serve --password):私有 TCP 中继通道用密码派生密钥做 ChaCha20-Poly1305 流加密,防第三方嗅探(运营商/中间人看不到内容; 服务器持有密码,可解密转发);TURN 中继用标准 long-term credential 认证 (防冒用),但标准 TURN 的数据面本身是明文——需要机密性时同样配合--key --key端到端加密:P2P 直连流量用--key派生密钥加密, 服务器也无法解密(即使密码泄露)
组合建议:自用/局域网直连多用 --key(端到端);打洞失败走中继时, 服务器密码至少保证"路上不裸奔"。
信令服务器可以设置密码吗(防止别人乱建房间)?
可以。服务器启动时加 --password:
frp-sh serve --addr 0.0.0.0:8080 --relay-addr 0.0.0.0:8081 --password 你的密码之后客户端必须在配置中填写同一密码(frp-sh config 向导第 4 步,或直接改 config.toml 加 password = "..."):
- 请求认证:所有信令请求校验密码,错误/缺失 → 401 拒绝
- 中继认证 + 加密:中继连接需带密码,流量加密
- 不设密码的服务器行为与原来完全一致(兼容旧客户端)
房间号会被别人猜中吗?
房间号主体为 6 位十六进制(约 1600 万组合)+ 12 小时 TTL,暴力扫描需在短时间访问服务器 1600 万次——低风险但非零。需要更高安全时:
- 使用长前缀自定义房间号,如
frp-sh game create --prefix my-long-room-2024 - 配合
--key加密(即使房间号泄露,无口令也无法解密)
其他
双方在同一 WiFi 下,怎么做到局域网直连?
无需任何操作——自动的。房主创建房间时会通告自己的局域网地址,访客加入时同时向 「公网地址 + 局域网地址」打洞。同网段时几秒内即输出 本地局域网直连 (LAN direct), 流量完全在局域网内,不经服务器,延迟最低(适合联机游戏)。
访客能访问房主局域网里的其他设备吗(NAS/打印机)?
可以,但默认不暴露。用 lan 系列(组网,类 Tailscale),且房主创建房间时需加 --expose-lan:frp-sh lan create --expose-lan 会自动通告局域网子网(如 192.168.1.0/24)并开启 IPv4 转发,访客 frp-sh lan join 自动添加经虚拟网卡的路由, 之后即可直接 ping / 访问房主局域网内的设备。若双方在同一网段,该子网会被自动跳过 以避免路由冲突。
访客侧同样可以加 --expose-lan(frp-sh lan join <房间号> --expose-lan),让房主 也能访问你自己的局域网。
game / dev 系列是纯端口转发,不提供访问对方局域网的能力。
Windows / macOS 上 lan 模式需要管理员权限吗?
需要。创建虚拟网卡、设置 IP、添加路由都属于特权操作。为免去手动「右键以管理员身份 运行」的麻烦:
- Windows:直接运行
frp-sh lan create/join即可——程序检测到权限不足时会 自动弹出 UAC 提权窗口,点一次「是」就以管理员继续运行(首次需确认,之后每次运行 仍会弹一次 UAC 确认),并自动放行虚拟网卡入站流量(否则对端 ping / 访问你会 被 Windows 防火墙拦截) - macOS / Linux:用
sudo frp-sh lan create/join运行 - Windows 的
wintun.dll由安装脚本自动下载(irm https://frp.sh/install.ps1 | iex)
game / dev 系列是纯端口转发,不需要管理员权限。
每台设备的虚拟 IP 是固定的吗?怎么管理(类似 VLAN)?
是的,每台设备有固定的虚拟 IP,三种方式(按优先级):
- 显式指定:
frp-sh lan join lan-xxx --ip 10.66.0.5 - 房主分配:房主
frp-sh lan create --guest-ips 10.66.0.2,10.66.0.3预留 IP 池, 访客按加入顺序拿号,同一设备重连复用同一 IP - UUID 自动派生:什么都不配时,由设备 ID 稳定派生(如
10.66.0.42), 同一台设备永远拿到同一个 IP
网段默认 10.66.0.0/24(相当于一个 VLAN)。想划分多个 VLAN 就用不同网段开不同 房间(--ip + --netmask 可指定任意网段)。同一房间内所有成员同网段、天然互通。
还需要填写 25565 吗?
0.5.0 已取消默认端口。Game 默认虚拟局域网,不要求隧道服务端口。指定游戏服务器或开发服务时,请填写实际 TCP/UDP 端口;25565 仅是某些游戏的示例,不能用于所有游戏。
invalid room id 校验规则
房间号格式为 前缀-6位hex(如 game-a3f9c2)。--prefix 仅保留小写字母数字与 -_,最长 16 字符。
会话怎么结束?
默认断线自动重连(按当前连接路径的退避策略),不会因链路抖动结束。真正结束的途径:
- 房主/访客
Ctrl-C(房主退出会删除房间) - 房间过期或被删除(双方自动结束)
支持 IPv6 吗?
信令、中继、打洞均使用标准 SocketAddr,支持 IPv6 地址(配置中写 [::1]:8080 形式)。打洞与 NAT 行为以实际网络环境为准。
可以在 Docker 里跑吗?
可以。静态二进制可直接放入镜像:
FROM ubuntu:24.04
COPY frp-sh /usr/local/bin/frp-sh
EXPOSE 8080/tcp 8080/udp 8081/tcp
CMD ["frp-sh", "serve", "--addr", "0.0.0.0:8080", "--relay-addr", "0.0.0.0:8081"]反馈
遇到文档未覆盖的问题,附上 frp-sh --verbose 的输出与网络环境描述反馈。