可以说我有两台电脑.
他们通过相互了解公共和私人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) 我正试图在软件中实现一个打孔功能.问题是,我正在使用已经建立的TCP服务器与用户进行通信.
这是我到目前为止所拥有的:
当然,例如端口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打孔测试都是在第9次测试中成功的.
似乎还有更多:
UDP绑定测试(?):端点独立绑定,端口预测很容易
因此,通过3G连接连接2个对等设备应该不会有任何问题(远远不及"家庭"NAT背后)......我是对的吗?
编辑4:
为了确定,我现在向两个不同的UDP服务器发送消息,以检查3G上的端口和本地端口是否相同.
长话短说,端口(本地和公共)在两台服务器上连接时都是一样的.所以在EDIT 2上完成的测试是正确的,udp是端点独立的,所以我不应该在进行打孔时遇到任何问题......(至少我的ISP)
我正在尝试完成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) 我正在尝试使用mingw工具链实现使用Windows套接字的TCP打孔.我认为这个过程是正确的,但这个漏洞似乎没有.我用这个作为参考.
我认为代码中没有问题,因为:
10060
)我错过了什么?
编辑:在进程资源管理器的帮助下,我看到其中一个客户端设法建立与对等方的连接.但是同行似乎并没有考虑要建立连接.
这是我用Wireshark捕获的内容.为了示例,服务器S和客户端A在同一PC上.服务器S侦听8060
重定向到该PC 的特定端口().B仍然尝试连接正确的IP,因为它看到S发送的A的公共地址是,因此使用S的公共IP .(我已用占位符替换了公共IP)localhost
编辑2:我认为混淆是由于传入和传出的连接请求数据都在同一端口上传输.这似乎弄乱了连接状态,因为我们不知道哪个套接字将从端口获取数据.如果我引用msdn:
该
SO_REUSEADDR
套接字选项允许套接字被另一个套接字强制绑定到一个端口在使用中.第二个套接字调用setsockopt,其中optname参数设置为SO_REUSEADDR
,并且optval参数设置为TRUE
在与原始套接字相同的端口上调用bind之前的布尔值.第二个套接字成功绑定后,绑定到该端口的所有套接字的行为都是不确定的.
但TCP Hole …
任何人都可以举一个UDP打孔的例子吗?
实际上,我想写一个聊天程序,当人们知道对方的IP时,人们可以聊天.但这两台机器都将在防火墙路由器后面.所以,我需要打一个洞才能沟通.
我想要一个功能,这样在调用函数时,一个洞就会被打孔,未来的通信将很容易进行 - 如果这不是太多要求:)
我正在使用UDP和UDT进行Holepunching.对于最终测试,我需要在不同的NAT类型(对称,全锥,限制锥,端口限制NAT)上测试应用程序.
有什么方法可以模拟这些吗?我期待的是某种虚拟盒子设置.我可以将PC用作路由器,以便根据我的需要进行配置吗?
一般来说,我们如何测试不同网络条件的应用程序?
我一直在阅读很多关于如何实现UDP打孔的内容但是出于某些原因我无法使其工作.
对于那些不熟悉udp打孔的人来说,这是我自己的定义:
目标是能够在服务器的帮助下在两个客户端(客户端A和客户端B)之间传输数据.因此,客户端A连接到服务器并发送其信息.客户B也这样做.服务器具有必要的信息,以便客户端A能够向客户端B发送数据,反之亦然.因此,服务器将该信息提供给两个客户端.一旦两个客户端都有关于彼此的信息,就可以在没有服务器帮助的情况下开始在这些客户端之间发送和接收数据.
我的目标是能够做我刚才描述的(udp打孔).在此之前,我认为能够从服务器连接到客户端会很有帮助.为此,我计划向服务器发送有关客户端的信息.一旦服务器收到该信息尝试从头开始连接到客户端.一旦我能够执行,我应该拥有开始实现真正的udp打孔所需的一切.
以下是我设置的方法:
顶级路由器的服务器和底部路由器连接到LAN端口.底部路由器(NAT)通过其WAN端口连接到顶级路由器.并且客户端计算机连接到底部路由器到其LAN端口之一.
因此,在该连接中,客户端能够看到服务器,但服务器无法看到客户端.
所以我在伪代码中完成的算法是:
服务器:
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) 我正在尝试一些p2p网络.在做了一些研究之后,我学到的最大障碍之一就是"如果客户端在NAT /防火墙后面怎么办",后来我发现了关于打孔的问题,但并不总能保证能够正常工作.
据我所知,我不明白它为什么会失败,这是我目前所知道的:
ip:port
在目录中ip:port
在目录中发布他ip:port
. (3)ip:port
.(5)ip:port
到他的本地的映射ip:port
,NAT只是将Bob公众收到的任何数据转发ip:port
给他的计算机.我希望借助具有静态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) 我最感兴趣的是移动设备的一般答案,但特定于Android的东西是可以接受的.
给定2个移动设备,我如何在它们之间建立连接.我是移动开发的新手,我不确定是什么类型的NAT移动设备.是否可以进行某种"打孔"(使用外部服务器来帮助建立连接)将它们连接在一起?
我看过这个问题,但它对我没有多大帮助,我仍然不知道如何获取IP和/或遍历NAT. Android - 两台设备之间的通信