这两天一直在弄UDP打洞,弄得晕头转向的。下面说说我对UDP打洞的一点理解,希望大家指点!
目标:实现两个只有内网IP地址的直接通信(不需要经过服务器的中转)
关键字:
1。NAT(网络地址解析):内网的主机向公网的服务器发送数据时,路由会利用NAT机制将内网的地址解析成公网的地址。
2。Session(会话):一个会话是由内部IpEndPoint和目的公网IpEndPoint组成的,在第一个udp包被发送出去的时候创建.
如下:如果client想向server发送一个udp数据包,在server看来client是Nath后的IpEndPoint:221.65.14.32:4000,这时Session记录了192.168.0.10:7000和60.65.54.41:5000
这样在server向221.65.14.32:4000发送数据时Nat会利用Session将数据发送到192.168.0.10:7000------------|     client       |----------|     Nat        |-------------|  server   |
------------192.168.0.10:7000--------->221.65.14.32:4000------------>60.65.54.41:5000
实现udp打洞:
前提:在一段时间内,内部主机利用相同的端口向不同服务器发送UDP数据包时Nat端会分配相同的端口
也就是说利用192.168.0.10:7000依次向server1:60.65.54.41:5000和server2:60.65.54.41:5200发送udp数据包时,从server1和server2来看client的地址都是221.65.14.32:4000。
我利用一下这段程序来测试:
//client,use one udpclient send each udp server a  udp packet 
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;namespace UdpTestClient
{
    class Program
    {
        static void Main(string[] args)
        {
            IPAddress addr =IPAddress.Parse("221.198.110.220");
            UdpClient client = new UdpClient();
            byte[] bytes=System.Text.Encoding.ASCII.GetBytes("fasdf");
            client.Send(bytes,bytes.Length,new IPEndPoint(addr,7100));
            Console.WriteLine("Just Wait five seconds...");
            System.Threading.Thread.Sleep(5000);
            client.Send(bytes, bytes.Length, new IPEndPoint(addr, 7200));
        }
    }
}先写到这里了,大家帮我看看对不对。

解决方案 »

  1.   

    能不能说一下你的session的,消息啊,我在使用tcp进行通讯呢,你应该也是研究p2p的吧,你上面说的有点像!
      

  2.   

    我觉得session 是由Nat创建的,它由Nat端的IpEndPoint唯一标识(221.65.14.32:4000),同时包含了内部网络的IpEndPoint(192.168.0.10:7000)和通信另一方的IpEndPoint(60.65.54.41:5000).
    这样内部主机192.168.0.10:7000向Nat地址60.65.54.41:5000发送的数据会被转发到目的主机60.65.54.41:5000
    同时:目的主机60.65.54.41:5000向Nat地址60.65.54.41:5000发送的数据会被转发到内部主机192.168.0.10:7000我现在也研究p2p,最近想做一个Udp的点对点聊天工具可是在udp打洞上遇到了一点问题
    希望和大家交流一下
      

  3.   

    那就是说有了session,就能不用tcp连接了,用它就能实现了吗?