p2p tcp nat 原理图+源码(原创)
现今网上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 = ; 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(), ));
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 = ; 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(), );
clinet.Client.Bind(bendi);
clinet.Connect(new IPEndPoint(IPAddress.Parse("请填写你的服务器ip"), ));
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[];
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();
}
}
}
有问题欢迎大家联系我
p2p tcp nat 原理图+源码(原创)的更多相关文章
- TCP/IP协议栈源码图解分析系列10:linux内核协议栈中对于socket相关API的实现
		题记:本系列文章的目的是抛开书本从Linux内核源代码的角度详细分析TCP/IP协议栈内核相关技术 轻松搞定TCP/IP协议栈,原创文章欢迎交流, byhankswang@gmail.com linu ... 
- 清晰易懂TCP通信原理解析(附demo、简易TCP通信库源码、解决沾包问题等)C#版
		目录 说明 TCP与UDP通信的特点 TCP中的沾包现象 自定义应用层协议 TCPLibrary通信库介绍 Demo演示 未完成功能 源码下载 说明 我前面博客中有多篇文章讲到了.NET中的网络编程, ... 
- 【TCP/IP】TCP服务器并发处理&源码
		前言 本笔记记录的是 单个服务端并发式处理多个客户端. 下次有空在发个 单线程多个服务端并发式处理多种客户端.其实就是本笔记的一个改良版,用到select() / poll() / epoll(). ... 
- Servlet在启动时加载的tomcat源码(原创)
		tomcat 8.0.36 知识点: 通过配置loadOnStartup可以设置Servlet是否在Tomcat启动时加载,以及按值大小进行有序加载,其最小有效值为0,最大有效值为Integer.MA ... 
- tomcat触发ServletContext初始化监听事件的源码(原创)
		tomcat 8.0.36 知识点: 动态监听器的好处可以根据环境条件进行选择性添加. 静态监听器有七类. ServletContextAttributeListener ServletRequest ... 
- [图解tensorflow源码] [原创]  Tensorflow 图解分析 (Session, Graph, Kernels, Devices)
		TF Prepare [图解tensorflow源码] 入门准备工作 [图解tensorflow源码] TF系统概述篇 Session篇 [图解tensorflow源码] Session::Run() ... 
- p2p技术之n2n源码核心简单分析一
		首先在开篇之前介绍下内网打洞原理 场景:一个服务器S1在公网上有一个IP,两个私网机器C1,C2 C1,C2分别由NAT1和NAT2连接到公网,我们需要借助S1将C1,C2建立直接的TCP连接,即由C ... 
- 以太坊系列之六: p2p模块--以太坊源码学习
		p2p模块 p2p模块对外暴露了Server关键结构,帮助上层管理复杂的p2p网路,使其集中于Protocol的实现,只关注于数据的传输. Server使用discover模块,在指定的UDP端口管理 ... 
- C# Winform C/S系统快速开发平台(源码+原创)
		C/S系统开发框架-企业版 V4.0 (Enterprise Edition) 简介: http://www.csframework.com/cs-framework-4.0.htm 适用软件:适合开 ... 
随机推荐
- “全能”选手—Django 1.10文档中文版Part2
			第一部分传送门 第三部分传送门 第四部分传送门 3.2 模型和数据库Models and databases 3.2.2 查询操作making queries 3.3.8 会话sessions 目录 ... 
- c# 生成SHA1加密字符串
			从网上找到的一种加密代码: var enstr ="abcdefg"; var strRes = Encoding.Default.GetBytes(enstr); HashAlg ... 
- [Excel] Worksheet.PasteSpecial
			PasteSpecial(Format, Link, DisplayAsIcon, IconFileName, IconIndex, IconLabel, NoHTMLFormatting) 1. F ... 
- sessionPageState与视图状态存储
			这个配置节甚是简单,在MSDN中的介绍也甚是简单:为 ASP.NET 应用程序配置页的视图状态设置. historySize的作用是设置要存储在页历史记录中的项数. 但是这根本是看不明白他是干嘛的,百 ... 
- XmlReader和XElement组合之读取大型xml文档
			简介 在.NET framework 中存在大量操作xml数据的类库和api,但在.NET framework 3.5后我们的首选一般就是linq to xml. linq to xml操作xml数据 ... 
- DDD心得
			使用DDD分层架构有哪些好处 帮你更集中的管理业务逻辑. 帮你降低各层间,以及各业务模块间的依赖关系. 帮你更方便的进行单元测试. 我的DDD分层架构使用经验 使用充血模型,将业务逻辑尽量放到领域实体 ... 
- ABP之模块
			ABP的反射 为什么先讲反射,因为ABP的模块管理基本就是对所有程序集进行遍历,再筛选出AbpModule的派生类,再按照以来关系顺序加载. ABP对反射的封装着重于程序集(Assembly)与类(T ... 
- java web学习总结(二十) -------------------监听器属性详解
			一.监听域对象中属性的变更的监听器 域对象中属性的变更的事件监听器就是用来监听 ServletContext, HttpSession, HttpServletRequest 这三个对象中的属性变更信 ... 
- jQuery.my – 实时的复杂的双向数据绑定
			jQuery.my 这个插件用于实时双向数据绑定.它发生变异给出的数据源对象,反映了用户与用户界面之间的相互作用.jQuery.my 提供了全面的验证,条件格式,复杂的依赖关系,运行形式结构操作. 马 ... 
- JS字符串反序输出
			function IsReverse(text){ return text.split('').reverse().join(''); } IsReverse("你是我的小丫小苹果" ... 
