英文文献: Peer-to-Peer Communication Across Network Address Translators(I)
中文翻译: UDP/TCP穿越NAT的P2P通信方法研究(UDP/TCP打洞 Hole Punching)
C++实现的源代码:(c++)TCP实现P2P通信、TCP穿越NAT的方法、TCP打洞
本论坛搜集: 关于C#TcpListener监听WAN IP实现QQ程序收集资料
一个简单说明: UDP打洞(UDP Hole Punching)原理
C#实现UDP穿越NAT程序运行效果图
(图一)运行在公网上的服务器程序,用于转发打洞消息.
(图二)运行在公网上的测试客户端程序A
(图三)运行在NAT网络上的测试客户端程序B
(图四) UDP打洞过程状态图
***阅读下面代码前请先了解UDP穿越NAT原理***
1.服务器主窗体源代码
public partial class frmServer : Form
{
private Server _server;
public frmServer()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
_server = new Server();
_server.OnWriteLog += new WriteLogHandle(server_OnWriteLog);
_server.OnUserChanged += new UserChangedHandle(OnUserChanged);
try
{
_server.Start();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
//刷新用户列表
private void OnUserChanged(UserCollection users)
{
listBox2.DisplayMember = "FullName";
listBox2.DataSource = null;
listBox2.DataSource = users;
}
//显示跟踪消息
public void server_OnWriteLog(string msg)
{
listBox1.Items.Add(msg);
listBox1.SelectedIndex = listBox1.Items.Count - 1;
}
private void button2_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void frmServer_FormClosing(object sender, FormClosingEventArgs e)
{
if (_server != null)
_server.Stop();
}
private void button3_Click(object sender, EventArgs e)
{
//发送消息给所有在线用户
P2P_TalkMessage msg = new P2P_TalkMessage(textBox1.Text);
foreach (object o in listBox2.Items)
{
User user = o as User;
_server.SendMessage(msg, user.NetPoint);
}
}
private void button6_Click(object sender, EventArgs e)
{
listBox1.Items.Clear();
}
}
如转载请注明本文来自易学网http://www.vjsdn.com/
2.服务器业务类
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using vjsdn.net.library;
using System.Windows.Forms;
namespace vjsdn.net.library
{
/// <summary>
/// 服务器端业务类
/// </summary>
public class Server
{
private UdpClient _server; //服务器端消息监听器
private UserCollection _userList; //在线用户列表
private Thread _serverThread;
private IPEndPoint _remotePoint; //远程用户请求的IP地址及端口
private WriteLogHandle _WriteLogHandle = null;
private UserChangedHandle _UserChangedHandle = null;
/// <summary>
/// 显示跟踪消息
/// </summary>
public WriteLogHandle OnWriteLog
{
get { return _WriteLogHandle; }
set { _WriteLogHandle = value; }
}
/// <summary>
/// 当用户登入/登出时触发此事件
/// </summary>
public UserChangedHandle OnUserChanged
{
get { return _UserChangedHandle; }
set { _UserChangedHandle = value; }
}