C#实现UDP打洞.docx
- 文档编号:8666395
- 上传时间:2023-02-01
- 格式:DOCX
- 页数:16
- 大小:19.75KB
C#实现UDP打洞.docx
《C#实现UDP打洞.docx》由会员分享,可在线阅读,更多相关《C#实现UDP打洞.docx(16页珍藏版)》请在冰豆网上搜索。
C#实现UDP打洞
C#实现UDP打洞
虽然打洞技术的实现源码在网上也可以找到,但用C#实现的源码并不多见。
另外下面的代码为了达到功能与界面的分离,采用了事件进行消息通信,程序具有一定的可移植性和可扩展性,也最能体现我的C#编码风格。
不过代码没有严格遵循模式设计的原则,希望网友们如果有更优化的代码能提出来共享一下。
总体上来说,下面的程序包还有它存在的使用价值和意义,所以发表出来共享一下。
下面是UDP打洞程序包的源码:
//WellKnown公用库
usingSystem;
usingSystem.IO;
usingSystem.Runtime.Serialization.Formatters.Binary;
usingSystem.Net;
usingSystem.Net.Sockets;
usingSystem.Collections;
namespaceP2PWellKnown
{
///
///UDP用户登录事件委托
///
///
///
publicdelegatevoidUdpUserLogInDelegate(objectsender,UDPSockEventArgse);
///
///一般UDP消息事件委托
///
///
///
publicdelegatevoidUdpMessageDelegate(objectsender,UDPSockEventArgse);
///
///初始化一个新连接的事件委托
///
///
///
publicdelegatevoidUdpNewConnectDelegate(objectsender,UDPSockEventArgse);
///
///P2P共享数据类
///
publicclassP2PConsts
{
///
///UDP服务器监听端口
///
publicconstintUDP_SRV_PORT =2280;
///
///TCP服务器监听端口
///
publicconstintTCP_SRV_PORT=2000;
}
///
///FormatterHelper序列化,反序列化消息的帮助类
///
publicclassFormatterHelper
{
publicstaticbyte[]Serialize(objectobj)
{
BinaryFormatterbinaryF=newBinaryFormatter();
MemoryStreamms=newMemoryStream(1024*10);
binaryF.Serialize(ms,obj);
ms.Seek(0,SeekOrigin.Begin);
byte[]buffer=newbyte[(int)ms.Length];
ms.Read(buffer,0,buffer.Length);
ms.Close();
returnbuffer;
}
publicstaticobjectDeserialize(byte[]buffer)
{
BinaryFormatterbinaryF=newBinaryFormatter();
MemoryStreamms=newMemoryStream(buffer,0,buffer.Length,false);
objectobj=binaryF.Deserialize(ms);
ms.Close();
returnobj;
}
}
///
///用于承载UDPSock信息的事件类
///
publicclassUDPSockEventArgs:
EventArgs
{
///
///要承载的消息
///
privatestringm_strMsg;
///
///用户信息
///
privatestringm_strUserName;
///
///触发该事件的公共终端
///
privateIPEndPointm_EndPoint;
///
///初始化UDPSock事件
///
///
publicUDPSockEventArgs(stringsMsg):
base()
{
this.m_strMsg=sMsg;
}
///
///远端用户名
///
publicstringRemoteUserName
{
get
{
returnm_strUserName;
}
set
{
m_strUserName=value;
}
}
///
///一般套接字消息
///
publicstringSockMessage
{
get
{
returnm_strMsg;
}
set
{
m_strMsg=value;
}
}
///
///公共远端节点
///
publicIPEndPointRemoteEndPoint
{
get
{
returnm_EndPoint;
}
set
{
m_EndPoint=value;
}
}
}
}
//UDPP2PSock.cs
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Text;
usingSystem.Net;
usingSystem.Net.Sockets;
usingSystem.Threading;
usingP2PWellKnown;
namespaceUDPP2P
{
///
///UDPP2P套接字管理类
///
publicclassUDPP2PSock
{
///
///用户登录事件
///
publiceventUdpUserLogInDelegateOnUserLogInU;
///
///一般UDP消息事件
///
publiceventUdpMessageDelegateOnSockMessageU;
///
///初始化一个新连接事件
///
publiceventUdpNewConnectDelegateOnNewConnectU;
///
///UDP服务器
///
privateUdpClientm_udpServer;
///
///UDP客户端
///
privateUdpClientm_udpClient;
///
///服务器实际上在本地机器上监听的
///端口,用于当一台计算机上同时启
///动两个可两以上服务器进程时,标
///识不同的服务器进程
///
privateintm_iMyServerPort;
///
///客户端在本地机器上实际使用的端口,
///用于当一台计算机上同时有两个或两
///个以上客户端进程在运行时,标识不
///同的客户端进程
///
privateintm_iMyClientPort;
///
///标识是否已成功创服务器
///
privateboolm_bServerCreated;
///
///标识是否已成功创建客户端
///
privateboolm_bClientCreated;
///
///服务器使用的线程
///
privateThreadm_serverThread;
///
///客户端使用的线程
///
privateThreadm_clientThread;
///
///打洞线程
///
//privateThreadm_burrowThread;
///
///远端节点
///
privateIPEndPointm_remotePoint;
///
///当前进程作为客户端的公共终端
///
privatestringm_strMyPublicEndPoint;
///
///当前进程作为客户端的私有终端
///
privatestringm_strMyPrivateEndPoint;
///
///用于接受信息的StringBuilder实例
///
privateStringBuilderm_sbResponse=newStringBuilder();
///
///P2P打洞时标识是否收到回应消息
///
privateboolm_bRecvAck=false;
///
///请求向其方向打洞的私有终端
///
privateIPEndPointm_requestPrivateEndPoint;
///
///请求向其方向打洞的公共终端
///
privateIPEndPointm_requestPublicEndPoint;
///
///打洞消息要发向的节点
///
privateToEndPointm_toEndPoint;
///
///用于标识是否已经和请求客户端建立点对连接
///
//privateboolm_bHasConnected=false;
///
///创建服务器或客户端的最大尝试
///次数,为(65536-60000),防止
///因不能创建而限入死循环或使用
///无效端口
///
privateconstintMAX_CREATE_TRY=5536;
///
///打洞时尝试连接的最大尝试次数
///
privateconstintMAX_CONNECT_TRY=10;
///
///构造函数,初始化UDPP2P实例
///
publicUDPP2PSock()
{
m_iMyServerPort=P2PConsts.UDP_SRV_PORT;
m_iMyClientPort=60000;
m_bClientCreated=false;
m_bServerCreated=false;
m_toEndPoint=newToEndPoint();
m_serverThread=newThread(newThreadStart(RunUDPServer));
m_clientThread=newThread(newThreadStart(RunUDPClient));
//m_burrowThread=newThread(newThreadStart(BurrowProc));
}
///
///创建UDP服务器
///
publicvoidCreateUDPSever()
{
intiTryNum=0;
//开始尝试创建服务器
while(!
m_bServerCreated&&iTryNum { try { m_udpServer=newUdpClient(m_iMyServerPort); m_bServerCreated=true; } catch { m_iMyServerPort++; iTryNum++; } } //创建失败,抛出异常 if(! m_bServerCreated&&iTryNum==MAX_CREATE_TRY) { thrownewException("创建服务器尝试失败! "); } m_serverThread.Start(); } /// ///创建UDP客户端 /// /// /// publicvoidCreateUDPClient(stringstrServerIP,intiServerPort) { intiTryNum=0; //开始尝试创建服务器 while(! m_bClientCreated &&iTryNum { try { m_udpClient =newUdpClient(m_iMyClientPort); m_bClientCreated =true; stringstrIPAddress=(System.Net.Dns.GetHostAddresses("localhost")[0]).ToString(); m_strMyPrivateEndPoint=strIPAddress+": "+m_iMyClientPort.ToString(); } catch { m_iMyClientPort++; iTryNum++; } } //创建失败,抛出异常 if(! m_bClientCreated &&iTryNum==MAX_CREATE_TRY) { thrownewException("创建客户端尝试失败! "); } IPEndPointhostPoint=newIPEndPoint(IPAddress.Parse(strServerIP),iServerPort); stringstrLocalIP=(System.Net.Dns.GetHostAddresses("localhost"))[0].ToString(); SendLocalPoint(strLocalIP,m_iMyClientPort,hostPoint); m_clientThread.Start(); } /// ///运行UDP服务器 /// privatevoidRunUDPServer() { while(true) { byte[]msgBuffer=m_udpServer.Receive(refm_remotePoint); m_sbResponse.Append(System.Text.Encoding.Default.GetString(msgBuffer)); CheckCommand(); Thread.Sleep(10); } } /// ///运行UDP客户端 /// privatevoidRunUDPClient()
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- C# 实现 UDP 打洞
![提示](https://static.bdocx.com/images/bang_tan.gif)