标签: hole-punching

Java UDP打孔示例 - 通过防火墙连接

可以说我有两台电脑.

他们通过相互了解公共和私人IP ice4j.

一个客户端正在侦听,另一个发送一些字符串.

我想通过UPD打孔来看到这种情况:

Let A be the client requesting the connection

Let B be the client that is responding to the request

Let S be the ice4j STUN server that they contact to initiate the connection
--
A sends a connection request to S

S responds with B's IP and port info, and sends A's IP and port info to B

A sends a UDP packet to B, which B's router firewall drops but it still
punches …
Run Code Online (Sandbox Code Playgroud)

java networking stun hole-punching

35
推荐指数
4
解决办法
2万
查看次数

在3G上没有经过UDP打孔

我正试图在软件中实现一个打孔功能.问题是,我正在使用已经建立的TCP服务器与用户进行通信.

这是我到目前为止所拥有的:

  • "A"向UDP服务器"US"发送消息(在端口9333上)
  • "US"将已连接的端口发送回"A"(端口31000 - localport 31005)
  • "A"向TCP服务器"TS"发送消息,说他想要连接到B(并给端口31000)
  • "TS"向"B"发送消息,给他"A"的端口(31000)和ip
  • "B"向"US"发送消息(在端口9333上)
  • "US"向"B"发送消息,告诉他他的端口45000(localport 45005)
  • "B"向"TS"发送消息给出是udp端口(45000)
  • "TS"向"A"发送消息,给出B的udp端口(45000)和ip
  • "A"开始在端口45000上向B的ip发送udp消息,并在localport 31005上收听
  • "B"开始向端口31000上的A的IP发送udp消息,并在localport 45005上收听

当然,例如端口31000,31005,45000和45005,每个端口改变的新连接,只有9333是静态的.

我知道有很多来回,比实际情况还要多.事实上,我必然会使用TCP服务器与两个用户进行通信,udp服务器只是将用户的端口返回给自己,因此它可以将其发送回TCP服务器.

但是,任何人都不会收到用户之间的消息......任何人都会知道为什么?


编辑:

我用http://nattest.net.in.tum.de/test.php测试了我的路由器,并且udp打孔工作正常,所以问题不是来自我的路由器,而是来自我的协议......

当用户在同一个NAT后面时,一切正常,当然它使用了private ip,但这意味着代码也在工作,所以每一个都会导致协议问题......


编辑2:

实际上,我做了一半的工作(问题实际上来自我的代码,而不是协议......我已经连接了2个用户,一个用3G连接iPhone,一个连接在Wifi上我的NAT.

有趣的(不是那么多)事情是,只有一个套接字能够在两个用户之间接收和发送数据.(由iphone发起的套接字)根据协议,我应该有2个连接良好的套接字,我错了吗?

所以我设法在我的NAT中打了一个洞,但实际上并没有在蜂窝NAT中.

当然,我立即测试了2台连接在3G上的iphone.没有人得到另一个人的信息.

我错过了有关手机NAT的内容吗?

PS:很抱歉更新我的问题,但由于我没有得到答案,我试图自己找...

PS 2:因为我设法在我的NAT中打了一个洞,我改变了标题,加上"在3G上"


编辑3:我再次运行http://nattest.net.in.tum.de/test.php测试,我的电脑通过我的iphone的3G连接连接到互联网.

这是结果: UDP HOLE PUNCHING RESULT

显然所有的udp打孔测试都是在第9次测试中成功的.

似乎还有更多:

UDP绑定测试(?):端点独立绑定,端口预测很容易

因此,通过3G连接连接2个对等设备应该不会有任何问题(远远不及"家庭"NAT背后)......我是对的吗?


编辑4:

为了确定,我现在向两个不同的UDP服务器发送消息,以检查3G上的端口和本地端口是否相同.

长话短说,端口(本地和公共)在两台服务器上连接时都是一样的.所以在EDIT 2上完成的测试是正确的,udp是端点独立的,所以我不应该在进行打孔时遇到任何问题......(至少我的ISP)

udp 3g hole-punching 3g-network

33
推荐指数
2
解决办法
1万
查看次数

UDP打孔实现

我正在尝试完成UDP打孔.我的理论基于这篇文章WIKI页面,但我面临着C#编码的一些问题.这是我的问题:

使用此处发布的代码,我现在能够连接到远程计算机并在同一端口上侦听传入连接(将2个UDP客户端绑定到同一端口).

由于某种原因,对同一端口的两个绑定相互阻止接收任何数据.我有一个响应我的连接的UDP服务器,所以如果我在将任何其他客户端绑定到端口之前先连接到它,我会得到它的响应.

如果我将另一个客户端绑定到该端口,则不会在任一客户端上接收数据.

以下是显示我的问题的2个代码片段.第一个连接到远程服务器以在NAT设备上创建规则,然后在另一个线程上启动侦听器以捕获传入的数据包.然后代码将数据包发送到本地IP,以便侦听器获取它.第二个只发送数据包到本地IP,以确保这是有效的.我知道这不是真正的打孔,因为我在不使用NAT设备的情况下将数据包发送给自己.我现在面临一个问题,如果我在NAT设备旁边使用计算机进行连接,我认为这不会有任何不同.

[编辑] 2/4/2012我尝试在我的网络上使用另一台计算机和WireShark(数据包嗅探器)来测试监听器.我看到从其他计算机传入的数据包但是没有被侦听器UDP客户端(udpServer)或发送方UDP客户端(客户端)接收.

[编辑] 2/5/2010我现在添加了一个函数调用,在初始发送和接收数据包之后关闭第一个UDP客户端,只有第二个UDP客户端才能侦听端口.这有效,我可以从该端口上的网络内部接收数据包.我现在将尝试从网络外部发送和接收数据包.我一发现就会发布我的发现.

使用此代码,我在侦听客户端上获取数据:

static void Main(string[] args)
{
    IPEndPoint localpt = new IPEndPoint(Dns.Resolve(Dns.GetHostName()).AddressList[0], 4545);

    ThreadPool.QueueUserWorkItem(delegate
    {
        UdpClient udpServer = new UdpClient();
        udpServer.ExclusiveAddressUse = false;
        udpServer.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
        udpServer.Client.Bind(localpt);

        IPEndPoint inEndPoint = new IPEndPoint(IPAddress.Any, 0);
        Console.WriteLine("Listening on " + localpt + ".");
        byte[] buffer = udpServer.Receive(ref inEndPoint); //this line will block forever
        Console.WriteLine("Receive from " + inEndPoint + " " + Encoding.ASCII.GetString(buffer) + ".");
    });

    Thread.Sleep(1000);

    UdpClient udpServer2 …
Run Code Online (Sandbox Code Playgroud)

c# udp traversal nat hole-punching

21
推荐指数
3
解决办法
2万
查看次数

TCP打孔

我正在尝试使用mingw工具链实现使用Windows套接字的TCP打孔.我认为这个过程是正确的,但这个漏洞似乎没有.我用这个作为参考.

  1. AB连接到服务器S.
  2. S发送到A,B的路由器IP +它用来连接S的端口
  3. SB做同样的事情
  4. 一个开始2个主题:
    • 一个线程尝试使用S发送的信息连接到B的路由器
    • 另一个线程正在等待连接到S时用于连接到其路由器的同一端口上的传入连接
  5. B做同样的事情

我认为代码中没有问题,因为:

  • AB确实互相使用ip和port
  • 当他们联系服务器时,他们都在监听他们用来连接路由器的端口
  • 它们都连接到正确的IP和端口但是超时(代码错误10060)

我错过了什么?

编辑:在进程资源管理器的帮助下,我看到其中一个客户端设法建立与对等方的连接.但是同行似乎并没有考虑要建立连接.

这是我用Wireshark捕获的内容.为了示例,服务器S和客户端A在同一PC上.服务器S侦听8060重定向到该PC 的特定端口().B仍然尝试连接正确的IP,因为它看到S发送的A的公共地址是,因此使用S的公共IP .(我已用占位符替换了公共IP)localhost

Wireshark的

编辑2:我认为混淆是由于传入和传出的连接请求数据都在同一端口上传输.这似乎弄乱了连接状态,因为我们不知道哪个套接字将从端口获取数据.如果我引用msdn:

SO_REUSEADDR套接字选项允许套接字被另一个套接字强制绑定到一个端口在使用中.第二个套接字调用setsockopt,其中optname参数设置为SO_REUSEADDR,并且optval参数设置为TRUE在与原始套接字相同的端口上调用bind之前的布尔值.第二个套接字成功绑定后,绑定到该端口的所有套接字的行为都是不确定的.

但TCP Hole …

windows tcp network-protocols winsock2 hole-punching

17
推荐指数
1
解决办法
9842
查看次数

UDP打孔算法

任何人都可以举一个UDP打孔的例子吗?

实际上,我想写一个聊天程序,当人们知道对方的IP时,人们可以聊天.但这两台机器都将在防火墙路由器后面.所以,我需要打一个洞才能沟通.

我想要一个功能,这样在调用函数时,一个洞就会被打孔,未来的通信将很容易进行 - 如果这不是太多要求:)

sockets udp hole-punching

17
推荐指数
2
解决办法
2万
查看次数

如何模拟不同的NAT行为

我正在使用UDP和UDT进行Holepunching.对于最终测试,我需要在不同的NAT类型(对称,全锥,限制锥,端口限制NAT)上测试应用程序.

有什么方法可以模拟这些吗?我期待的是某种虚拟盒子设置.我可以将PC用作路由器,以便根据我的需要进行配置吗?

一般来说,我们如何测试不同网络条件的应用程序?

networking udp network-programming nat hole-punching

16
推荐指数
2
解决办法
3597
查看次数

UDP打孔.让服务器与客户交谈

我一直在阅读很多关于如何实现UDP打孔的内容但是出于某些原因我无法使其工作.

对于那些不熟悉udp打孔的人来说,这是我自己的定义:

目标是能够在服务器的帮助下在两个客户端(客户端A和客户端B)之间传输数据.因此,客户端A连接到服务器并发送其信息.客户B也这样做.服务器具有必要的信息,以便客户端A能够向客户端B发送数据,反之亦然.因此,服务器将该信息提供给两个客户端.一旦两个客户端都有关于彼此的信息,就可以在没有服务器帮助的情况下开始在这些客户端之间发送和接收数据.

我的目标是能够做我刚才描述的(udp打孔).在此之前,我认为能够从服务器连接到客户端会很有帮助.为此,我计划向服务器发送有关客户端的信息.一旦服务器收到该信息尝试从头开始连接到客户端.一旦我能够执行,我应该拥有开始实现真正的udp打孔所需的一切.

以下是我设置的方法:

在此输入图像描述

顶级路由器的服务器和底部路由器连接到LAN端口.底部路由器(NAT)通过其WAN端口连接到顶级路由器.并且客户端计算机连接到底部路由器到其LAN端口之一.

因此,在该连接中,客户端能够看到服务器,但服务器无法看到客户端.

所以我在伪代码中完成的算法是:

  • 客户端连接到服务器.
  • 客户端将一些UDP包发送到服务器以打开NAT上的某些端口
  • 将信息发送到服务器上客户端正在侦听的端口.
  • 一旦服务器收到该信息尝试从头开始连接到客户端.

这是代码中的实现:

服务器:

static void Main()
{     
    /* Part 1 receive data from client */
    UdpClient listener = new UdpClient(11000);
    IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, 11000);
    string received_data;
    byte[] receive_byte_array = listener.Receive(ref groupEP);       
    received_data = Encoding.ASCII.GetString(receive_byte_array, 0, receive_byte_array.Length);

    // get info
    var ip = groupEP.Address.ToString();
    var port = groupEP.Port;

    /* Part 2 atempt to connect to client from scratch */
    // now atempt to send data to …
Run Code Online (Sandbox Code Playgroud)

c# sockets networking udp hole-punching

16
推荐指数
2
解决办法
1万
查看次数

p2p打孔有什么困难?

我正在尝试一些p2p网络.在做了一些研究之后,我学到的最大障碍之一就是"如果客户端在NAT /防火墙后面怎么办",后来我发现了关于打孔的问题,但并不总能保证能够正常工作.

据我所知,我不明白它为什么会失败,这是我目前所知道的:


在此输入图像描述
基于上图,这就是我如何理解如何建立成功的连接.

  1. Alice通过创建与目录服务器的连接来加入网络(1).发生这种情况时,Alice的 NAT会创建从她的公共IP到本地ip的映射.
  2. 目录服务器接收连接并将Alice的公共存储ip:port在目录中
  3. Bob做同样的事情(2),加入网络并ip:port在目录中发布他
  4. 爱丽丝想和鲍勃沟通.所以她从目录中查找Bob's ip:port. (3)
  5. Alice发送了她从服务器获得的Bob的 数据ip:port.(5)
  6. 由于Bob还有从is ip:port到他的本地的映射ip:port,NAT只是将Bob公众收到的任何数据转发ip:port给他的计算机.
  7. 同一作品爱丽丝
    我希望我能清楚地解释我的理解.我的问题是,这有什么困难或不可靠的?我必须清楚地遗漏一些东西.你能解释一下它是什么吗?

networking p2p hole-punching

14
推荐指数
3
解决办法
4934
查看次数

UDP打孔Java示例

我希望借助具有静态IP的服务器与两个客户端进行UDP打孔.服务器在端口7070和7071上等待两个客户端.之后,它会相互发送IP地址和端口.这部分工作正常.但是我无法在两个客户之间建立通信.我在不同的Wifi网络和3G移动网络中尝试了代码.客户端程序抛出IO-Exception"无路由到主机".客户端代码用于两个客户端.一旦用7070端口执行,一次用7071执行.

您认为我是否正确实施了UDP打孔概念?有什么想法让它发挥作用?这是服务器代码,然后是客户端代码.

谢谢你的帮助.

服务器代码:

public class UDPHolePunchingServer {

    public static void main(String args[]) throws Exception {

    // Waiting for Connection of Client1 on Port 7070
    // ////////////////////////////////////////////////

    // open serverSocket on Port 7070
    DatagramSocket serverSocket1 = new DatagramSocket(7070);

    System.out.println("Waiting for Client 1 on Port "
            + serverSocket1.getLocalPort());

    // receive Data
    DatagramPacket receivePacket = new DatagramPacket(new byte[1024], 1024);
    serverSocket1.receive(receivePacket);

    // Get IP-Address and Port of Client1
    InetAddress IPAddress1 = receivePacket.getAddress();
    int port1 = receivePacket.getPort();
    String msgInfoOfClient1 = IPAddress1 + "-" + …
Run Code Online (Sandbox Code Playgroud)

java sockets udp tunneling hole-punching

12
推荐指数
1
解决办法
1万
查看次数

直接在两个移动设备之间进行通信

我最感兴趣的是移动设备的一般答案,但特定于Android的东西是可以接受的.

给定2个移动设备,我如何在它们之间建立连接.我是移动开发的新手,我不确定是什么类型的NAT移动设备.是否可以进行某种"打孔"(使用外部服务器来帮助建立连接)将它们连接在一起?

我看过这个问题,但它对我没有多大帮助,我仍然不知道如何获取IP和/或遍历NAT. Android - 两台设备之间的通信

mobile android nat hole-punching

10
推荐指数
1
解决办法
3259
查看次数