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协议穿透
  • 基础版本不含身份验证
  • 需要保持客户端持续运行
  • 实际使用需添加异常处理

该实现通过端口映射建立双向隧道,服务端监听两个端口分别处理客户端连接和公网请求,客户端负责建立到内网服务的连接。数据通过流复制实现双向转发。