基于C#实现的UPnP端口映射程序

 更新时间:2026年02月26日 08:35:44   作者:yong9990  
本文介绍了基于C#实现的UPnP端口映射程序,该程序包含服务器端和客户端,支持TCP端口穿透和自动NAT穿透,服务器端实现UPnP端口映射和TCP服务端,客户端实现UPnP客户端类,程序支持多协议、自动重连机制和安全增强,需要的朋友可以参考下

基于C#实现的UPnP端口映射程序,包含服务器端和客户端实现,支持TCP端口穿透和自动NAT穿透:

一、核心实现原理

  1. UPnP协议:通过路由器自动映射内网端口到公网
  2. 双通道通信:服务器监听内网端口,客户端通过公网IP+映射端口连接
  3. 动态IP获取:通过外部服务获取公网IP地址

二、服务器端实现(支持自动端口映射)

1. UPnP端口映射类(UPnPHelper.cs)

using System;
using System.Net;
using NATUPNPLib;

public class UPnPHelper : IDisposable
{
    private UPnPNAT _nat;
    private IStaticPortMappingCollection _mappings;

    public UPnPHelper()
    {
        try
        {
            _nat = new UPnPNAT();
            _mappings = _nat.StaticPortMappingCollection;
        }
        catch (COMException ex)
        {
            throw new InvalidOperationException("UPnP服务不可用", ex);
        }
    }

    public bool AddPortMapping(int externalPort, int internalPort, string internalIP, ProtocolType protocol, string description = "UPnP Port Forwarding")
    {
        try
        {
            _mappings.Add(externalPort, protocol.ToString().ToUpper(), internalPort, internalIP, true, description);
            return true;
        }
        catch (COMException ex)
        {
            Console.WriteLine($"UPnP映射失败: {ex.Message}");
            return false;
        }
    }

    public void RemovePortMapping(int externalPort, ProtocolType protocol)
    {
        try
        {
            _mappings.Remove(externalPort, protocol.ToString().ToUpper());
        }
        catch (COMException ex)
        {
            Console.WriteLine($"UPnP解除映射失败: {ex.Message}");
        }
    }

    public string GetExternalIP()
    {
        using (var client = new WebClient())
        {
            string response = client.DownloadString("http://checkip.dyndns.org/");
            return System.Text.RegularExpressions.Regex.Match(response, @"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b").Value;
        }
    }

    public void Dispose()
    {
        _nat?.Dispose();
    }
}

public enum ProtocolType
{
    TCP = 0,
    UDP = 1
}

2. TCP服务端(Server.cs)

using System.Net;
using System.Net.Sockets;

public class Server
{
    private Socket _serverSocket;
    private UPnPHelper _upnp;

    public Server(int port)
    {
        _serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        _upnp = new UPnPHelper();
    }

    public void Start()
    {
        try
        {
            // 设置UPnP映射
            string internalIP = Dns.GetHostEntry(Dns.GetHostName()).AddressList
                .FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork)?.ToString();
            
            if (!_upnp.AddPortMapping(8080, 8080, internalIP, ProtocolType.TCP))
            {
                throw new InvalidOperationException("UPnP端口映射失败");
            }

            string externalIP = _upnp.GetExternalIP();
            Console.WriteLine($"服务器已启动 - 外网访问地址: {externalIP}:8080");

            _serverSocket.Bind(new IPEndPoint(IPAddress.Any, 8080));
            _serverSocket.Listen(10);

            while (true)
            {
                var client = _serverSocket.Accept();
                _ = Task.Run(() => HandleClient(client));
            }
        }
        finally
        {
            _upnp?.Dispose();
        }
    }

    private void HandleClient(Socket client)
    {
        using (var ns = new NetworkStream(client))
        using (var sr = new StreamReader(ns))
        using (var sw = new StreamWriter(ns))
        {
            string msg = sr.ReadLine();
            Console.WriteLine($"收到消息: {msg}");
            sw.WriteLine($"ECHO: {msg}");
            sw.Flush();
        }
    }
}

三、客户端实现

1. UPnP客户端类(UPnPClient.cs)

using System.Net;
using System.Net.Sockets;

public class UPnPClient
{
    private string _externalIP;
    private int _externalPort;

    public void Connect(string serverIP, int serverPort)
    {
        // 通过UPnP获取外部IP和端口
        using (var client = new WebClient())
        {
            string response = client.DownloadString("http://checkip.dyndns.org/");
            _externalIP = System.Text.RegularExpressions.Regex.Match(response, @"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b").Value;
        }

        _externalPort = serverPort;

        // 建立TCP连接
        var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        socket.Connect(new IPEndPoint(IPAddress.Parse(_externalIP), _externalPort));

        using (var ns = new NetworkStream(socket))
        using (var sr = new StreamReader(ns))
        using (var sw = new StreamWriter(ns))
        {
            sw.WriteLine("Hello Server");
            sw.Flush();

            string response = sr.ReadLine();
            Console.WriteLine($"服务器响应: {response}");
        }
    }
}

四、主程序入口

1. 服务器端启动

class Program
{
    static void Main(string[] args)
    {
        var server = new Server(8080);
        server.Start();
    }
}

2. 客户端连接

class Program
{
    static void Main(string[] args)
    {
        var client = new UPnPClient();
        client.Connect("服务器公网IP", 8080); // 替换为实际公网IP
    }
}

五、关键功能扩展

1. 多协议支持

// 在UPnPHelper中扩展UDP支持
public bool AddUdpPortMapping(int externalPort, int internalPort, string internalIP)
{
    return AddPortMapping(externalPort, internalPort, internalIP, ProtocolType.UDP);
}

2. 自动重连机制

// 在客户端添加重试逻辑
public void ConnectWithRetry(string serverIP, int serverPort, int maxRetries = 3)
{
    int attempt = 0;
    while (attempt < maxRetries)
    {
        try
        {
            Connect(serverIP, serverPort);
            return;
        }
        catch (Exception ex)
        {
            attempt++;
            Console.WriteLine($"连接失败 ({attempt}/{maxRetries}): {ex.Message}");
            Thread.Sleep(2000);
        }
    }
}

3. 安全增强

// 添加TLS加密
public void StartSecureServer(int port)
{
    _serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    _serverSocket.Bind(new IPEndPoint(IPAddress.Any, port));
    _serverSocket.Listen(10);

    using (var sslStream = new SslStream(_serverSocket.Accept(), false))
    {
        sslStream.AuthenticateAsServer(GetCertificate());
        // 处理加密通信...
    }
}

六、部署与测试

1. 环境要求

  • Windows 10/11 专业版及以上(需启用UPnP服务)
  • 路由器开启UPnP功能
  • 防火墙允许TCP端口8080

2. 测试步骤

  1. 在服务器端运行程序
  2. 查看控制台输出的外网IP和端口
  3. 在客户端输入该地址进行连接
  4. 验证双向通信是否正常

七、常见问题解决

问题现象解决方案
UPnP映射失败检查路由器UPnP设置,重启路由器
无法获取外网IP更换检测地址为https://api.ipify.org
连接超时检查防火墙规则,确保端口开放
数据包丢失启用TCP窗口缩放因子优化

以上就是基于C#实现的UPnP端口映射程序的详细内容,更多关于C# UPnP端口映射程序的资料请关注脚本之家其它相关文章!

相关文章

  • 详解c#索引(Index)和范围(Range)

    详解c#索引(Index)和范围(Range)

    这篇文章主要介绍了c#索引(Index)和范围(Range)的相关资料,帮助大家更好的理解和学习c#,感兴趣的朋友可以了解下
    2020-10-10
  • C#书写规范

    C#书写规范

    C#书写规范...
    2007-03-03
  • C#中遍历DataSet数据集对象实例

    C#中遍历DataSet数据集对象实例

    这篇文章主要介绍了C#中遍历DataSet数据集对象实例,经常忘记如何操作DataSet,这里记下来并分享,让需要的朋友可以参考下
    2014-08-08
  • C#集合本质之链表的用法详解

    C#集合本质之链表的用法详解

    本文详细讲解了C#集合本质之链表的用法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-08-08
  • C# winfrom 模拟ftp文件管理实现代码

    C# winfrom 模拟ftp文件管理实现代码

    从网上找到的非常好用的模拟ftp管理代码,整理了一下,希望对需要的人有帮助
    2014-01-01
  • 基于Unity3D实现3D照片墙效果

    基于Unity3D实现3D照片墙效果

    Unity3D不仅仅可以开发游戏,还有非常多的开发方向。本文就将用Unity3D制作出一个3D照片墙的效果,文中的示例代码讲解详细,感兴趣的可以了解一下
    2022-03-03
  • 超炫酷的WPF实现Loading控件效果

    超炫酷的WPF实现Loading控件效果

    这篇文章主要介绍了超炫酷的WPF实现Loading控件效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2015-11-11
  • C# Socket 发送&接收&返回 简单应用实例

    C# Socket 发送&接收&返回 简单应用实例

    下面小编就为大家分享一篇C# Socket 发送&接收&返回 简单应用实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2017-11-11
  • C#中常用的运算符总结

    C#中常用的运算符总结

    在本篇文章里小编给大家分享了关于C#中常用的运算符的知识点总结,需要的朋友们跟着学习下。
    2019-03-03
  • 在C#中创建、读取和更新Excel文档的操作指南

    在C#中创建、读取和更新Excel文档的操作指南

    在日常开发中,C# 操作 Excel 文档是普遍且重要的需求,无论是数据导入导出、报表生成,还是数据分析,Excel 都扮演着不可或缺的角色,本文将深入探讨如何在 C# 中高效地创建、读取和更新 Excel 文档,需要的朋友可以参考下
    2025-12-12

最新评论