lidgren 介绍和使用 (四)------ p2p
p2p前几年比较流行,因为他不需要服务器,通过不同客户端内网,就可以交互。
他的原理也很简单,就是先内网发送给服务器,了解到自己的外网ip和端口。然后内网向对方外网发送数据。
由于nat,也就是路由器的阻拦,第一次发送数据会被抛弃,但发送方的 路由器却记录了 对方的ip,这样对方 发送外网 给你,就不会被 nat路由器阻拦,当然,nat开放通道的时间很短,1--2秒,所以两台客户端要同时多次发送,确保成功。我做了一个小demo
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace udp_Client_demo { public partial class Form1 : Form { private static IPEndPoint epServer; private static UdpClient local; private int port; public Form1() { InitializeComponent(); epServer = new IPEndPoint(IPAddress.Parse("103.200.30.194"), 11000); local = new UdpClient(9001); //绑定本机IP和端口,9001 } private void conn_Click(object sender, EventArgs e) { string strSend = "wwww"; byte[] sendData = Encoding.ASCII.GetBytes(strSend); //开始异步发送,启动一个线程,该线程启动函数是:SendCallback,该函数中结束挂起的异步发送 local.BeginSend(sendData, sendData.Length, epServer, new AsyncCallback(SendCallback), null); //开始异步接收启动一个线程,该线程启动函数是:ReceiveCallback,该函数中结束挂起的异步接收 local.BeginReceive(new AsyncCallback(ReceiveCallback), null); mes.Text += ss; } private void SendCallback(IAsyncResult iar) { int sendCount = local.EndSend(iar); if (sendCount == 0) { Console.WriteLine("Send a message failure..."); } } private string ss; private void ReceiveCallback(IAsyncResult iar) { byte[] receiveData = local.EndReceive(iar, ref epServer); ss = Encoding.ASCII.GetString(receiveData); } private void button1_Click(object sender, EventArgs e) { Int32.TryParse(ports.Text, out port); //设置服务器端IP和端口 epServer = new IPEndPoint(IPAddress.Parse(horts.Text), port); } private void button2_Click(object sender, EventArgs e) { string strSend = mes.Text; byte[] sendData = Encoding.ASCII.GetBytes(strSend); //开始异步发送,启动一个线程,该线程启动函数是:SendCallback,该函数中结束挂起的异步发送 local.BeginSend(sendData, sendData.Length, epServer, new AsyncCallback(SendCallback), null); //开始异步接收启动一个线程,该线程启动函数是:ReceiveCallback,该函数中结束挂起的异步接收 local.BeginReceive(new AsyncCallback(ReceiveCallback), null); } } }
用winform 写的,原理很简单,先点击连接服务器,在服务器里面看到自己和对方的 外网ip,然后填写对方ip,然后点击连接客户端,这个时候,点击发送客户端,对方就能获得数据。
不过有一点必须注意!!!
同nat,也就是 2台客户端 都在一个 路由器下,不能被接收,想想也是,一个路由,他能自己给自己开通道吗,另外手机 4g包括热点,不能,因为 4g网络的 路由 是 对称 型的,就是端口 改变的,所以测试时候,条件还是
很苛刻的,我家楼下正好有 小店,无线路由器能 照到我家,配合我家的路由,才能测试。
好了,说道这里,有人要说,如今都是手机上网,那么 如何 点对点 通信呢?
答案就是 upnp!!! 下一篇,最终篇《upnp 通信》,大家期待。