首页 > 学院 > 开发设计 > 正文

p2ptcpnat原理图+源码(原创)

2019-11-14 13:50:10
字体:
来源:转载
供稿:网友

现今网上p2p的 udp nat穿透 文章 多如牛毛, p2p tcp nat的文章寥寥无几 ,up主研究了几天 终于有所收获,特来向大家分享,请大家多多支持!

 

1、首先你要有台外网服务器 或者 电信的运营商 支持转发的路由器(具体过程不多说,请自行百度)

2、一台能上网的电脑(内网里面的电脑 不然没有意义)

 

核心代码就是:

socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);

作用就是让已经连接的端口可以再次监听 从而实现tcp nat 的目的

原理图:

外网服务器端代码 (ps:up主穷 买不起服务器 只能用公司的路由器转发 ,请见谅!):

using System;using System.Collections.Generic;using System.Linq;using System.Net;using System.Net.Sockets;using System.Text;using System.Threading;namespace TcpNatTestS{    class PRogram    {        public static ipAddress GetLocalIP()        {            try            {                string HostName = Dns.GetHostName(); //得到主机名                IPHostEntry IpEntry = Dns.GetHostEntry(HostName);                for (int i = 0; i < IpEntry.AddressList.Length; i++)                {                    //从IP地址列表中筛选出IPv4类型的IP地址                    //AddressFamily.InterNetwork表示此IP为IPv4,                    //AddressFamily.InterNetworkV6表示此地址为IPv6类型                    if (IpEntry.AddressList[i].AddressFamily == AddressFamily.InterNetwork)                    {                        return IpEntry.AddressList[i];                    }                }                return IPAddress.Any;            }            catch (Exception ex)            {                return IPAddress.Any;            }        }        static void Main(string[] args)        {            TcpListener tcp = new TcpListener(new IPEndPoint(GetLocalIP(), 8085));            tcp.Start();            new Thread(e =>            {                while (true)                {                    var lianjie = tcp.AcceptTcpClient();                    //new TcpClient().Connect((IPEndPoint)lianjie.Client.RemoteEndPoint);                    lianjie.Client.Send(UnicodeEncoding.Unicode.GetBytes("你的外网ip是:" + lianjie.Client.RemoteEndPoint));                    Console.WriteLine("内网服务器: 本地端口:" + lianjie.Client.LocalEndPoint + "远程端口:" + lianjie.Client.RemoteEndPoint);                }            }).Start();            Console.ReadKey();        }    }}

 

内网客户端(你需要自己填写外网服务器ip):

 

using System;using System.Collections.Generic;using System.Linq;using System.Net;using System.Net.Sockets;using System.Text;using System.Threading;namespace TcpNatTestA{    class Program    {        public static IPAddress GetLocalIP()        {            try            {                string HostName = Dns.GetHostName(); //得到主机名                IPHostEntry IpEntry = Dns.GetHostEntry(HostName);                for (int i = 0; i < IpEntry.AddressList.Length; i++)                {                    //从IP地址列表中筛选出IPv4类型的IP地址                    //AddressFamily.InterNetwork表示此IP为IPv4,                    //AddressFamily.InterNetworkV6表示此地址为IPv6类型                    if (IpEntry.AddressList[i].AddressFamily == AddressFamily.InterNetwork)                    {                        return IpEntry.AddressList[i];                    }                }                return IPAddress.Any;            }            catch (Exception ex)            {                return IPAddress.Any;            }        }        static void Main(string[] args)        {            new Thread(e =>            {                TcpClient clinet = new TcpClient();                clinet.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);                var bendi = new IPEndPoint(GetLocalIP(), 7896);                clinet.Client.Bind(bendi);                clinet.Connect(new IPEndPoint(IPAddress.Parse("请填写你的服务器ip"), 8085));                TcpListener tcp = new TcpListener(bendi);                tcp.Server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);                tcp.Start();                new Thread(() =>                {                    while (true)                    {                        var jiqi= tcp.AcceptTcpClient();                        Console.WriteLine("内网客户机: 本地端点:" + bendi + " 远程端点:" + jiqi.Client.RemoteEndPoint);                    }                }).Start();                clinet.Client.Send(UnicodeEncoding.Unicode.GetBytes("呵呵呵呵"));                byte[] hh = new byte[500];                var weishu = clinet.Client.Receive(hh);                byte[] temp = new byte[weishu];                Array.Copy(hh, temp, weishu);                //Console.WriteLine("远程端口:"+clinet.Client.RemoteEndPoint);                Console.WriteLine(UnicodeEncoding.Unicode.GetString(temp));            }).Start();            Console.ReadKey();        }    }}

 

 

 有问题欢迎大家联系我

 


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表