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  通信》,大家期待。

posted on 2019-01-13 17:16  太粗难进  阅读(637)  评论(0编辑  收藏  举报