C#实现UDP打洞 原理及代码(三)
来源:互联网 发布:Windows 10专业版64位 编辑:程序博客网 时间:2024/05/06 22:20
/// <summary>
/// 发送消息
/// </summary>
/// <param name="strMsg">消息内容</param>
/// <param name="REP">接收节点</param>
public void SendData(string strMsg,IPEndPoint REP)
{
byte[] byMsg = System.Text.Encoding.Default.GetBytes(strMsg.ToCharArray());
m_udpClient.Send(byMsg, byMsg.Length, REP);
}
/// <summary>
/// 发送消息,服务器专用
/// </summary>
/// <param name="strMsg">消息内容</param>
/// <param name="REP">接收节点</param>
private void ServerSendData(string strMsg,IPEndPoint REP)
{
byte[] byMsg = System.Text.Encoding.Default.GetBytes(strMsg.ToCharArray());
m_udpServer.Send(byMsg, byMsg.Length, REP);
}
/// <summary>
/// 发送本地节点信息
/// </summary>
/// <param name="strLocalIP">本地IP</param>
/// <param name="iLocalPort">本地端口</param>
public void SendLocalPoint(string strLocalIP, int iLocalPort,IPEndPoint REP)
{
string strLocalPoint = "/x01/x02" + strLocalIP + ":" + iLocalPort.ToString() + "/x02/x01";
SendData(strLocalPoint, REP);
}
/// <summary>
/// 同时向指定的终端(包括公共终端和私有终端)打洞
/// </summary>
/// <param name="pubEndPoint">公共终端</param>
/// <param name="prEndPoint">私有终端</param>
/// <returns>打洞成功返回true,否则返回false</returns>
public void StartBurrowTo(IPEndPoint pubEndPoint, IPEndPoint prEndPoint)
{
Thread burrowThread = new Thread(new ThreadStart(BurrowProc));
m_toEndPoint.m_privateEndPoint = prEndPoint;
m_toEndPoint.m_publicEndPoint = pubEndPoint;
burrowThread.Start();
}
/// <summary>
/// 打洞线程
/// </summary>
private void BurrowProc()
{
IPEndPoint prEndPoint = m_toEndPoint.m_privateEndPoint;
IPEndPoint pubEndPoint = m_toEndPoint.m_publicEndPoint;
int j = 0;
for (int i = 0; i < MAX_CONNECT_TRY; i++)
{
SendData("/x01/x07/x07/x01", prEndPoint);
SendData("/x01/x07/x07/x01", pubEndPoint);
//等待接收线程标记修改
for (j = 0; j < MAX_CONNECT_TRY; j++)
{
if (m_bRecvAck)
{
m_bRecvAck = false;
SendData("/x01/x07/x07/x01", prEndPoint);
Thread.Sleep(50);
SendData("/x01/x07/x07/x01", pubEndPoint);
UDPSockEventArgs args = new UDPSockEventArgs("");
args.RemoteEndPoint = pubEndPoint;
if (OnNewConnectU != null)
{
OnNewConnectU(this, args);
}
//Thread .Sleep (System .Threading.Timeout .Infinite );
return;
}
else
{