FrpSharp.Core
1.0.3
See the version list below for details.
dotnet add package FrpSharp.Core --version 1.0.3
NuGet\Install-Package FrpSharp.Core -Version 1.0.3
<PackageReference Include="FrpSharp.Core" Version="1.0.3" />
<PackageVersion Include="FrpSharp.Core" Version="1.0.3" />
<PackageReference Include="FrpSharp.Core" />
paket add FrpSharp.Core --version 1.0.3
#r "nuget: FrpSharp.Core, 1.0.3"
#:package FrpSharp.Core@1.0.3
#addin nuget:?package=FrpSharp.Core&version=1.0.3
#tool nuget:?package=FrpSharp.Core&version=1.0.3
FrpSharp — frpc Client Ported to C#
FrpSharp is a C#/.NET port of the frpc client from frp (Go language, v0.70.1), a fast reverse proxy that exposes local servers behind NAT or firewalls to the Internet. This project ports only the client (frpc); it remains fully protocol-compatible with the original Go frps server.
- Target framework: .NET 8 LTS (multi-targeting
net8.0;net10.0; .NET 10 enabled only when a dependency requires it) - Source scale: ~17,260 lines of Go client code (~102 files, tests excluded)
- Estimated C# output: ~24,500 lines including unit tests
- Timeline: 6 phases, ~61–76 working days (~3–3.5 months)
Solution Layout
FrpSharp/
├── FrpSharp.sln
├── Directory.Build.props # Shared target framework / version config
├── src/
│ ├── FrpSharp.Core/ # Core library: Protocol, Auth, Config, Transport,
│ │ # Proxy, Visitor, Plugin, NatHole, Util
│ ├── FrpSharp.Client/ # Integration wrapper (NuGet: FrpSharp.Client)
│ │ # JSON config, DI extensions, HostedService
│ └── FrpSharp.App/ # CLI entry point (Program.cs)
├── tests/
│ ├── FrpSharp.Core.Tests/ # Unit tests (xUnit)
│ └── FrpSharp.IntegrationTests/ # End-to-end tests against real Go frps
├── conf/
│ └── appsettings.example.json # Example JSON configuration
├── docs/ # Phase-0 evaluation reports (yamux, golib, KCP, QUIC)
├── migrate/ # Full migration plan & task checklists
└── go-refs/ # Vendored Go sources used as porting reference
NuGet Packages
FrpSharp.Client — for ASP.NET Core integration (most users want this)
dotnet add package FrpSharp.Client
// Program.cs — one-line integration
builder.Services.AddFrpSharp(builder.Configuration.GetSection("FrpSharp"));
// appsettings.json
{
"FrpSharp": {
"serverAddr": "your-server.com",
"serverPort": 7000,
"auth": { "method": "token", "token": "your-token" },
"proxies": [
{ "type": "tcp", "name": "web", "localIP": "127.0.0.1", "localPort": 8080, "remotePort": 80 }
]
}
}
FrpSharp.Core — low-level protocol library
Use FrpSharp.Core directly only when you need to build a custom client without ASP.NET Core DI, work with the wire protocol directly, or implement your own proxy/transport layers.
dotnet add package FrpSharp.Core
See Configuration Guide for details.
Hot-Reload Configuration
FrpSharp supports hot-reloading proxy configurations without restarting the client:
Using ProxyConfigHelper (Recommended for API-driven scenarios)
The simplest way to manage proxy configurations at runtime:
using FrpSharp.Core.ConfigMgmt;
// Upsert (update if exists, add if not): returns "added" or "updated"
var result = ProxyConfigHelper.UpsertTcpProxy(service, "web", "127.0.0.1", 8080, 80);
// Upsert HTTP proxy
ProxyConfigHelper.UpsertHttpProxy(service, "myweb", "127.0.0.1", 5000, ["example.com"]);
// Upsert + Apply + Save to file in one step
var result = ProxyConfigHelper.UpsertAndSave(service, "web", configurer, "frpc.toml");
// Async version
var result = await ProxyConfigHelper.UpsertAndSaveAsync(service, "web", configurer, "frpc.toml");
// Remove proxy and save
ProxyConfigHelper.RemoveProxy(service, "web");
ProxyConfigHelper.Apply(service);
ProxyConfigHelper.SaveToFile(service, "frpc.toml");
Automatic File Watching
Enable automatic config reload when the configuration file changes:
// Create service with config file path
await using var service = new FrpSharpService(config, "frpc.toml");
// Enable automatic hot-reload (watches file changes)
service.EnableAutoReload();
await service.RunAsync(cancellationToken);
Manual Reload via API
Trigger config reload via Admin API:
# POST request to reload configuration
curl -X POST http://127.0.0.1:7400/api/reload
# GET request (compatible with Go frpc)
curl http://127.0.0.1:7400/api/reload
Manual Reload via Code
// Reload configuration programmatically
await service.ReloadConfigAsync();
How It Works
- File Watcher: Uses
FileSystemWatcherto monitor configuration file changes - Debounce: 500ms debounce delay prevents multiple reloads from a single save operation
- Diff-based Update: Only adds/removes/restarts proxies whose configuration has changed
- Zero Downtime: Existing connections are preserved when possible
See docs/appsettings.md for more details.
Migration Phases
| Phase | Scope | Output |
|---|---|---|
| 1. Infrastructure | Protocol layer, config models, utility libraries | Wire v1/v2 handshake working |
| 2. Core services | Service / Control / Connector / TLS | TCP proxy end-to-end via Go frps |
| 3. Proxy system | All proxies, visitors, plugins, health checks, Admin API | TCP/UDP/HTTP/HTTPS/STCP/SUDP working |
| 4. Transport extensions | WebSocket, QUIC, Yamux multiplexing, KCP | WS/QUIC transports usable |
| 5. Advanced features | XTCP NAT traversal, OIDC auth, config hot-reload | P2P connections working |
| 6. Polish & release | Integration tests, packaging, docs | Single-file builds for Windows/Linux/macOS |
Technology Choices
| Area | Choice |
|---|---|
| JSON | System.Text.Json (source generators) |
| Config format | TOML via Tomlyn |
| CLI | System.CommandLine |
| Logging | Serilog |
| Admin API | ASP.NET Core Minimal APIs |
| Crypto | System.Security.Cryptography (AES-GCM/HMAC) |
| QUIC | System.Net.Quic (MsQuic, ALPN = frp) |
| Multiplexing | Custom Yamux port (compatible with frp's fork) |
| Compression | Snappier (Snappy) |
| Concurrency | System.Threading.Channels (goroutine channel equivalent) |
| Packaging | dotnet publish single-file |
Native AOT Support
FrpSharp is fully compatible with Native AOT compilation, producing tiny, fast-starting native executables:
- Zero trim warnings — all types annotated for trimming safety
- Source-generated JSON —
FrpSharpJsonContextgenerates serialization code at compile time - No reflection-based serialization — polymorphic proxy/visitor deserialization uses custom
JsonConverterwith source-generated type info - NuGet packages — both
FrpSharp.ClientandFrpSharp.Coreare AOT-ready out of the box
# Publish as native AOT single binary
dotnet publish -r linux-x64 -p:PublishAot=true
dotnet publish -r win-x64 -p:PublishAot=true
# Or use FrpSharp.Client in your own AOT-compiled ASP.NET Core app
dotnet add package FrpSharp.Client
Compatibility with Go frpc
- P0 (must): Wire v1 protocol, TCP proxy, TLS transport, token auth, heartbeat
- P1 (important): Wire v2 + AEAD, UDP/HTTP/HTTPS/STCP/SUDP proxies & visitors, work-conn encryption/compression, Admin API, health checks, WebSocket transport, yamux TCP multiplexing
- P2 (optional): Plugin system, QUIC, XTCP P2P NAT traversal, OIDC, config hot-reload, Proxy Protocol
- P3 (low): KCP transport, virtual network (vnet/TUN)
Compatibility is verified by running against the original Go frps, comparing captured packets between Go frpc and FrpSharp, and replaying the relevant official frp e2e test cases.
Reference Sources (go-refs/)
Vendored Go codebases used as porting references: frp (client), yamux / yamux-fork, quic-go, kcp-go, golib, go-proxyproto, go-socks5.
Documentation
- Build Guide / 编译部署指南 (中文) — how to build, publish, and deploy FrpSharp on all platforms
- Differences / 与 Go 版本差异 (中文) — protocol compatibility and implementation differences vs Go frpc
- Performance Report / 性能报告 (中文) — benchmark results for message codec, crypto, and rate limiter
- Proxy Configuration Examples / 代理配置示例 — example TOML configs for TCP, UDP, HTTP, HTTPS, STCP, XTCP, SUDP proxies
The complete migration plan lives in migrate/, including per-phase design docs, dependency mapping & NuGet selection, risk register, test strategy, subtask acceptance criteria, and a topologically ordered executable task list. Phase-0 evaluation reports (yamux diff, golib audit, KCP/QUIC feasibility) are in docs/.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- KcpSharp (>= 0.8.8)
- ReedSolomon (>= 2.0.0)
- Serilog (>= 4.4.0)
- Snappier (>= 1.3.1)
- Tomlyn (>= 2.10.1)
-
net8.0
- KcpSharp (>= 0.8.8)
- ReedSolomon (>= 2.0.0)
- Serilog (>= 4.4.0)
- Snappier (>= 1.3.1)
- Tomlyn (>= 2.10.1)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on FrpSharp.Core:
| Package | Downloads |
|---|---|
|
FrpSharp.Client
FRP client library for .NET — embed FRP tunneling into any ASP.NET Core application via appsettings.json and DI |
GitHub repositories
This package is not used by any popular GitHub repositories.