程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> p2p tcp nat 原理圖+源碼(原創),p2pnat

p2p tcp nat 原理圖+源碼(原創),p2pnat

編輯:C#入門知識

p2p tcp nat 原理圖+源碼(原創),p2pnat


現今網上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();
        }
    }
}

 

 

 有問題歡迎大家聯系我

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved