博主最早接触frp的xtcp是在2024年,当时遇到了一个对udp限制极为苛刻的园区网络,只有xtcp能够穿越重重阻碍提供一个毫秒级的点对点互联。后来对面逐渐独立,这套方案也就被博主完全忘在脑后了,也并未深究。
然而,去年9月博主在宿舍开始使用移动宽带,通过Tailscale连接办公室的rustdesk时常出现卡成ppt的情况。这段时间里,常常只能依靠腾讯和阿里200M的轻量应用服务器中继才能够获得比较理想的访问效果,但是这样在教育网中会带来50ms以上的访问延迟。

最近突然冒出来个想法,既然校园网有多个出口,那么是不是可以在校园网移动出口和移动宽带之间打一个P2P的洞呢?这样也恰好可以不受运营商跨网的约束。然而现实是Tailscale在实际测试中始终无法建立Direct Connection,直到我想起了frp……

一、环境检测
进行p2p打洞需要双方网络环境的NAT映射和过滤行为属于Endpoint-independent或Address-dependent,而在Address and Port-dependent行为下(类似NAT4)不满足常规打洞需求。
简而言之,我们可以通过frpc自带的./frpc nathole discover命令进行检测,结果中两端至少有一端为EasyNAT才具备使用xtcp打洞的可能性。
frp:GitHub – fatedier
NatTypeTester:GitHub – HMBSbige
博主位于办公室的落地端NAT类型使用NatTypeTester测试udp为Symmetric(NAT4),使用frpc测试tcp为Behavior No Change的EasyNAT。

位于宿舍的入口端NAT类型使用NatTypeTester测试udp为Port Restricted Cone(NAT3),使用frpc测试tcp同样为Behavior No Change的EasyNAT。
二者虽然实测在Tailscale中无法打洞直连,然而其nat行为却满足xtcp打洞的基础条件。
二、配置文件
frps服务端配置与常规的一致,仅用于数据交换:
|
1 2 3 4 5 6 7 8 9 |
## 服务端连接信息 bindPort = 7700 auth.token = "my_auth_token" ## 服务端面板信息 webServer.addr = "0.0.0.0" webServer.port = 7500 webServer.user = "my_admin_username" webServer.password = "my_admin_password" |
位于办公室的frpc落地端配置:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
## frps服务端信息 serverAddr = "1.1.1.1" serverPort = 7700 auth.token = "my_auth_token" ## stun打洞服务器信息 natHoleStunServer = "stun.easyvoip.com:3478" ## 转发落地信息 [[proxies]] # 配置名称及类型 name = "p2p_proxy" type = "xtcp" # 转发到目标IP及端口 localIP = "127.0.0.1" localPort = 443 # 配置密钥 secretKey = "my_secert" # 禁止NAT穿越虚拟组网 natTraversal.disableAssistedAddrs = true |
位于宿舍的frpc访问端配置:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
## frps服务端信息 serverAddr = "1.1.1.1" serverPort = 7700 auth.token = "my_auth_token" ## stun打洞服务器信息 natHoleStunServer = "stun.easyvoip.com:3478" ## 转发入口信息 [[visitors]] # 配置名称及类型 name = "p2p_visitor" type = "xtcp" # 对应落地端配置名称 serverName = "p2p_xtcp" # 配置密钥 secretKey = "my_secert" # 转发至本机的入口监听 bindAddr = "0.0.0.0" bindPort = 443 # 禁止NAT穿越虚拟组网 natTraversal.disableAssistedAddrs = true |
服务端frps与两侧客户端frpc配置完成后,访问该端口即可触发握手流程,成功后会提示successful。部分软件(如rustdesk)可能无法主动出发握手流程,可使用tcping类工具进行手动触发后再进行连接。

在配置文件中,如果你的两端位于ZeroTier、Tailscale或EasyTier等虚拟局域网内,则必须保留natTraversal配置,否则xtcp可能会通过虚拟局域网进行打洞。
此外,满足xtcp使用的stun服务器需开启RFC5780支持,并使用两个IP监听3478与3479端口分别用于请求和信息返回,无法使用常规仅使用3478端口的公开stun服务器。如需使用Coturn自建,请参考这条issue(点击前往)。其中,验证可用的stun服务器如下:
|
1 2 3 4 |
stun.easyvoip.com:3478 stun.voipstunt.com:3478 stun.cheapvoip.com:3478 stun.voipgain.com:3478 |
三、结语
在国内的网络互联中,UDP常常受到QoS的影响,这也导致Tailscale一类以UDP为传输协议的组网工具一定的局限性。实测从宿舍到校园网的端口通过xtcp连接延迟仅3ms,单线程测速更是一秒内打满博主本地的200M带宽,rustdesk也终于丝滑流畅。
之前其实挺想研究下更符合国情的EasyTier的,可惜目前Tailscale网络已过于庞大,等一个契机吧~
*原创文章,转发请注明出处