参考了网上的一篇文章,由于时间长了,具体地址不知道了。

引入了一个DLL: Interop.NATUPNPLib.dll,实现穿透局域网,进行Socket通信。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using NATUPNPLib;
using System.Threading;
using System.Text.RegularExpressions;
using System.IO;

namespace _22UPnP穿透内网
{
    class Program
    {
        static void Main(string[] args)
        {
            //获取Host Name
            string serverName = Dns.GetHostName();
            Console.WriteLine("Server名称:" + serverName);
            //从当前Host Name解析IP地址,筛选IPv4地址是本机的内网IP地址。
            IPAddress internalIP = Dns.GetHostEntry(serverName).AddressList
                .Where(i => i.AddressFamily == AddressFamily.InterNetwork)
                .FirstOrDefault();
            Console.WriteLine("Server内网IP:" + internalIP);

            UPnPNAT upnp = new UPnPNAT();
            IStaticPortMappingCollection staticPortMappingCollection = upnp.StaticPortMappingCollection;
            if (staticPortMappingCollection == null)
            {
                Console.WriteLine("没有检测到路由器,或者路由器不支持UPnP功能。");
                return;
            }

            int internalPort = 3898;//Server的端口号
            int externalPort = 4343;//对应映射的外部端口号

            staticPortMappingCollection.Add(
                externalPort,//外网端口
                "TCP",//协议类型
                internalPort,//内网端口
                internalIP.ToString(),//内网IP地址
                true,//是否开启
                "UPNP_Test"//描述
                );

            Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            EndPoint serverEndPoint = new IPEndPoint(internalIP, internalPort);
            serverSocket.Bind(serverEndPoint);
            serverSocket.Listen(1);
            Console.WriteLine("开启服务端监听......\n");

            Thread serverThread = new Thread(() => {
                Socket socket = null;
                while (true)
                {
                    if (socket!= null || (socket = serverSocket.Accept()) != null)
                    {
                        byte[] byteRec = new byte[1024*1024];//设置消息接收缓存区
                        int msgLen = socket.Receive(byteRec);
                        string msgRec = Encoding.UTF8.GetString(byteRec,0,msgLen);
                        Console.WriteLine("来自Client的消息:\n{0}", msgRec);
                    }
                }
            });
            serverThread.IsBackground = true;
            serverThread.Start();

            //外网IP变量
            string externalIP;
            //正则
            var regex = @"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b";
            Console.WriteLine("开始获取外网IP......");
            using (var webclient = new WebClient())
            {
                var rawRes = webclient.DownloadString("http://checkip.dyndns.org/");
                externalIP = Regex.Match(rawRes, regex).Value;
            }

            Console.WriteLine("获取外网IP成功:" + externalIP);

            Thread clientThread = new Thread(() =>
            {
                ClientConnectToServer(IPAddress.Parse(externalIP), externalPort);
            });
            clientThread.Start();

            Console.ReadKey();
        }

        static void ClientConnectToServer(IPAddress remoteIP, int remotePort)
        {
            Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            clientSocket.Connect(new IPEndPoint(remoteIP, remotePort));
            IPEndPoint remoteEndPoint = clientSocket.RemoteEndPoint as IPEndPoint;
            for (int i = 0; i < 3; i++)
            {
                string msgFromClient = string.Format("Hello, this msg is from Client. \n{2}\n[Remote IP: {0}, Remote Port: {1} ]\n",
                    remoteEndPoint.Address, remoteEndPoint.Port, DateTime.Now
                );
                byte[] bytes = Encoding.UTF8.GetBytes(msgFromClient);
                //客户端向服务端发送消息
                clientSocket.Send(bytes);
                Thread.Sleep(1000);
            }
        }
    }
}

附:源码下载地址: http://download.csdn.net/detail/frombegintoend/5688855

附有Interop.NATUPNPLib.dll

C#用UPnP穿透内网的更多相关文章

  1. n2n网络穿透内网

    目录 前言 配置 网络拓扑: 公网服务器的配置 公司电脑的配置 家里笔记本的配置 注意事项 使用n2n网络 n2n的各edge之间传输数据 补充:NAT类型 后记 前言 在家里的时候比较经常需要对公司 ...

  2. 穿透内网,连接动态ip,内网ip打洞-----p2p实现原理(转)

    源: 穿透内网,连接动态ip,内网ip打洞-----p2p实现原理

  3. 1.使用frp穿透内网

    1.前因后果 1.1弃用ngrok 为节约服务器成本,花了500多块买了一个华为云得1G 1核心 5M得云服务器.然后用ngrok来穿透内网.一直用得还  但是今天在弄nginx得时候发现 ngrok ...

  4. centos7下使用n grok编译服务端和客户端穿透内网

    (发现博客园会屏蔽一些标题中的关键词,比如ngrok.内网穿透,原因不知,所以改了标题才能正常访问,) 有时候想在自己电脑.路由器或者树莓派上搭建一些web.vpn等服务让自己用,但是自己的电脑一般没 ...

  5. frp端口映射穿透内网

    前言 frp 是一个高性能的反向代理应用,可以轻松地进行内网穿透,对外网提供服务,支持 TCP.UDP.HTTP.HTTPS 等协议类型,并且 web 服务支持根据域名进行路由转发. Github: ...

  6. FtpServer穿透内网访问配置踩笔记

    FtpServer穿透内网访问配置踩笔记 引言 FtpServer是服务器文件远程管理常用方式. 以前在局域网配置Ftp服务器以及使用公网上的Ftp服务均未碰到问题,固未对Ftp传输进行深入了解. 然 ...

  7. frp穿透内网使用vsftpd服务

    本篇文章将会介绍如何使用frp穿透内网以及如何在centos8环境下安装和使用vsftpd,最后在公网通过frp穿透内网使用ftp. 一.内网穿透神器frp frp 是一个专注于内网穿透的高性能的反向 ...

  8. QQ通信原理及QQ是怎么穿透内网进行通信的? (转)

    原:http://f543711700.iteye.com/blog/978044#bc2344608 QQ是一个基于TCP/UDP协议的通讯软件 发送消息的时候是UDP打洞,登陆的时候使用HTTP~ ...

  9. [转载]QQ通讯原理及QQ是怎么穿透内网的

    QQ是一个基于TCP/UDP协议的通讯软件 发送消息的时候是UDP打洞,登陆的时候使用HTTP~因为登陆服务器其实就是一个HTTP服务器,只不过不是常用的那些,那个服务器是腾讯自行开发的!!! 一.登 ...

随机推荐

  1. 转: Github访问慢解决办法

    from: https://yq.aliyun.com/articles/36744 Github访问慢解决办法   zxiaofan 2016-04-20 17:25:00 浏览2156 评论0 摘 ...

  2. 部署Zipkin分布式性能追踪日志系统的操作记录

    Zipkin是Twitter的一个开源项目,是一个致力于收集Twitter所有服务的监控数据的分布式跟踪系统,它提供了收集数据,和查询数据两大接口服务. 部署Zipkin环境的操作记录:部署Zipki ...

  3. iOS之block

    1. Block的声明和线程安全Block属性的声明,首先需要用copy修饰符,因为只有copy后的Block才会在堆中,栈中的Block的生命周期是和栈绑定的,可以参考之前的文章(iOS: 非ARC ...

  4. RelayCommand命令

    原文:http://www.cnblogs.com/xiepeixing/archive/2013/08/13/3255152.html 常用Wpf开发中我们在ViewModel中实现INotifyP ...

  5. C#获取枚举描述代码

    public class MusterEnum { /// 获取枚举的描述信息 /// </summary> /// <param name="e">传入枚 ...

  6. 字符串相似度算法(编辑距离算法 Levenshtein Distance)(转)

    在搞验证码识别的时候需要比较字符代码的相似度用到“编辑距离算法”,关于原理和C#实现做个记录. 据百度百科介绍: 编辑距离,又称Levenshtein距离(也叫做Edit Distance),是指两个 ...

  7. PowerDesigner打开设计文件后提示failed to read the fileXXX的解决办法

    擦,一身盗汗.一向的设计信息都在设计图里!竟然坏了,坏了!!!!! 惊.怒.悲 固然可以经由过程数据库当前状况反向工程.然则那么注解.我写的提示这些器材都邑消散. 比来的备份是10天前,恢复也会有必然 ...

  8. ubuntu上怎么设置默认python命令是执行python3而不是python2

    来源:https://segmentfault.com/q/1010000003713912 alternatives这么好的机制用起来呀. shell里执行: sudo update-alterna ...

  9. 如何使用Native Messaging API 打开window程序

    问 如何使用Native Messaging API 打开window程序 cmd javascript terminal chrome Tychio 2013年03月26日提问 关注 1 关注 收藏 ...

  10. Win7 Qt4.8.5+QtCreator2.8.0+mingw配置过程

    1:安装包 百度盘下载链接: Mingw: :安装步骤 1.首先安装qt creator,双击qt-creator-windows-opensource-2.8.0,注意安装目录不要有空格和特殊字符, ...