Dotnet
C#实现基础内网穿透服务的分步骤解决方案:
1. 创建控制台项目
2. 服务端代码(部署在公网服务器):
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
public class Server
{
    private TcpListener _controlListener;
    private TcpListener _publicListener;
    private TcpClient _clientBridge;
    public void Start(int controlPort, int publicPort)
    {
        _controlListener = new TcpListener(IPAddress.Any, controlPort);
        _publicListener = new TcpListener(IPAddress.Any, publicPort);
        
        _controlListener.Start();
        _publicListener.Start();
        // 客户端连接线程
        new Thread(() => {
            while(true)
            {
                var client = _controlListener.AcceptTcpClient();
                new Thread(() => HandleClient(client)).Start();
            }
        }).Start();
        // 公网请求处理线程
        new Thread(() => {
            while(true)
            {
                var publicClient = _publicListener.AcceptTcpClient();
                if(_clientBridge != null)
                {
                    BridgeConnections(publicClient, _clientBridge);
                }
            }
        }).Start();
    }
    private void HandleClient(TcpClient client)
    {
        _clientBridge = client;
        // 保持连接心跳
        while(client.Connected)
        {
            Thread.Sleep(1000);
        }
        _clientBridge = null;
    }
    private void BridgeConnections(TcpClient src, TcpClient dst)
    {
        new Thread(() => ForwardData(src.GetStream(), dst.GetStream())).Start();
        new Thread(() => ForwardData(dst.GetStream(), src.GetStream())).Start();
    }
    private void ForwardData(NetworkStream src, NetworkStream dst)
    {
        byte[] buffer = new byte[4096];
        while(true)
        {
            int bytesRead = src.Read(buffer, 0, buffer.Length);
            dst.Write(buffer, 0, bytesRead);
        }
    }
}3. 客户端代码(运行在内网机器):
using System;
using System.Net.Sockets;
using System.Threading;
public class Client
{
    public void Connect(string serverIp, int controlPort, string targetIp, int targetPort)
    {
        var client = new TcpClient();
        client.Connect(serverIp, controlPort);
        while(true)
        {
            if(client.GetStream().DataAvailable)
            {
                HandleServerRequest(client, targetIp, targetPort);
            }
            Thread.Sleep(100);
        }
    }
    private void HandleServerRequest(TcpClient serverClient, string targetIp, int targetPort)
    {
        var targetClient = new TcpClient();
        targetClient.Connect(targetIp, targetPort);
        
        BridgeConnections(serverClient, targetClient);
    }
    private void BridgeConnections(TcpClient src, TcpClient dst)
    {
        new Thread(() => ForwardData(src.GetStream(), dst.GetStream())).Start();
        new Thread(() => ForwardData(dst.GetStream(), src.GetStream())).Start();
    }
    private void ForwardData(NetworkStream src, NetworkStream dst)
    {
        byte[] buffer = new byte[4096];
        while(true)
        {
            int bytesRead = src.Read(buffer, 0, buffer.Length);
            dst.Write(buffer, 0, bytesRead);
        }
    }
}4. 使用方式:
服务端启动:
new Server().Start(8888, 8080); // 控制端口8888,公网端口8080客户端连接:
new Client().Connect("公网IP", 8888, "127.0.0.1", 80); // 映射本地80端口5. 注意事项:
- 需要配置服务器防火墙放行端口
 - 支持TCP协议穿透
 - 基础版本不含身份验证
 - 需要保持客户端持续运行
 - 实际使用需添加异常处理
 
该实现通过端口映射建立双向隧道,服务端监听两个端口分别处理客户端连接和公网请求,客户端负责建立到内网服务的连接。数据通过流复制实现双向转发。