我需要的是,我将打开一个UDP
监听X
端口(本地机器)的服务器,并且 machine(public IP)
可以向UDP
我发送数据包.我的机器没有public IP
.基本上我需要stun
.
我正在测试stuntman
服务器/客户端项目.我在服务器(公共IP)中运行stuntman-server.在我的系统中运行客户端(本地IP).我要求为端口映射ip/9999
port.
./stunclient --mode full --protocol udp --localport 9999 stun.server.ip
Stun服务器返回IP和端口.我做了什么,然后,打开一个UDP
在我的本地系统服务器(使用Java),并开始在监听9999
端口和发送UDP
的消息other machine (which has public IP)
,以mapped IP/port
通过STUN服务器返回.但我无法收到任何数据.您可以假设我的服务器/客户端代码(用java编写)在本地网络中正常工作.
流:
My machine ->>>>>stun request for 9999 port and my ip ------> stun server My machine <<<<<<<<<<<<<<<<<
selbie.. 8
您没有发布
stunclient
运行结果,但我想它看起来像下面这样:$ stunclient --mode full --localport 9999 stun.stunprotocol.org Binding test: success Local address: 192.168.1.8:9999 Mapped address: 1.2.3.4:9999 Behavior test: success Nat behavior: Endpoint Independent Mapping Filtering test: success Nat filtering: Address and Port Dependent Filtering我猜你的行为测试是"端点独立",过滤测试是"地址和端口相关",因为它们是家庭中最常见的,并且大多与上面描述的相匹配.(又称"端口限制NAT").
无论如何,这意味着您已经在自己和STUN服务器之间创建了一个端口映射.在上面的示例中,我的公共IP地址是1.2.3.4.并且很常见,但并非总是如此,我的本地端口(9999)与公共端口相同.
在内部,您的NAT保留一个逻辑表,如下所示:
------------------------------------------------------------------------------------ || LOCAL IP | LOCAL PORT || EXT PORT || REMOTE IP | REMOTE PORT || ||================================================================================|| || 192.168.1.8 | 9999 || 9999 || 107.23.150.92 | 3478 || ------------------------------------------------------------------------------------因为您从端口9999向stun服务器(107.23.150.92)发送了数据包,所以NAT会在其表中创建一个端口映射条目几分钟.当数据包从Internet到达NAT /路由器时,它会查询该表.当响应从STUN服务器的IP:端口返回时,NAT能够根据上表中的"远程"字段将其转发到NAT后面的计算机.
但是您和希望从中接收数据的"其他公共机器"之间没有端口映射.假设该另一台机器的IP地址是2.4.6.8并且它正在尝试从它的本地端口8888发送.表中的NAT仍然没有任何内容可以将来自2.4.6.8:8888的流量映射到后面的主机NAT.因此,当流量从不在表中的主机到达NAT时,NAT只知道将数据包丢弃在地板上.有一种称为"Cone NAT"的NAT分类可以使用,但这些并不常见.
在您的情况下,有一个简单的解决方法.从STUN服务器获取端口映射后,将另一个数据报从同一本地端口(9999)发送到要从中接收数据的远程主机(和远程端口).远程主机可以简单地忽略此数据报,但它有效地在NAT上创建另一个端口映射条目
------------------------------------------------------------------------------------ || LOCAL IP | LOCAL PORT || EXT PORT || REMOTE IP | REMOTE PORT || ||================================================================================|| || 192.168.1.8 | 9999 || 9999 || 107.23.150.92 | 3478 || || 192.168.1.8 | 9999 || 9999 || 2.4.6.8 | 8888 || ------------------------------------------------------------------------------------这个简单的1字节数据包到2.4.6.8:8888允许NAT将流量从该地址转发回NAT后面的主机.
换句话说,使用您自己的网络流命名法:
My machine:9999 ---->[STUN BINDING REQUEST]--->stun server:3478 My machine:9999 <----[STUN BINDING RESPONSE mapped IP:port]<--- stun server:3478 My machine:9999 [Open socket on port 9999] My machine:9999 ---->[1 byte datagram] -------> 'other:8888' My machine:9999 <---- [UDP to public IP:port obtained in step 2]<----'other:8888'通常,在正常的P2P流中,两个端点都与STUN服务器一起发现它们的端口映射.然后使用另一个服务来交换IP:彼此之间的端口信息.根据您的描述,您可以在程序之间手动交换这些值,这对于测试来说很合适.
如果另一台机器在公共互联网上,从技术上讲,您不需要STUN.第一台机器(在NAT后面)可以直接发送到远程IP和端口,说"向我发送一些数据".远程端只检查此消息的对等地址和端口以决定将其发送回的位置.端口映射已创建.一些RTSP客户端假设服务器是公共的
关于套接字NAT遍历的基础知识的答案就在这里.
我碰巧认识了STUNTMAN的开发者.他是一个相当好的人,外表漂亮,非常聪明.他们还说他和我看起来相似,并且与我们的名字几乎完全相同.如果您对STUN和NAT遍历有疑问,可以随时直接给他发邮件.
1> selbie..:您没有发布
stunclient
运行结果,但我想它看起来像下面这样:$ stunclient --mode full --localport 9999 stun.stunprotocol.org Binding test: success Local address: 192.168.1.8:9999 Mapped address: 1.2.3.4:9999 Behavior test: success Nat behavior: Endpoint Independent Mapping Filtering test: success Nat filtering: Address and Port Dependent Filtering我猜你的行为测试是"端点独立",过滤测试是"地址和端口相关",因为它们是家庭中最常见的,并且大多与上面描述的相匹配.(又称"端口限制NAT").
无论如何,这意味着您已经在自己和STUN服务器之间创建了一个端口映射.在上面的示例中,我的公共IP地址是1.2.3.4.并且很常见,但并非总是如此,我的本地端口(9999)与公共端口相同.
在内部,您的NAT保留一个逻辑表,如下所示:
------------------------------------------------------------------------------------ || LOCAL IP | LOCAL PORT || EXT PORT || REMOTE IP | REMOTE PORT || ||================================================================================|| || 192.168.1.8 | 9999 || 9999 || 107.23.150.92 | 3478 || ------------------------------------------------------------------------------------因为您从端口9999向stun服务器(107.23.150.92)发送了数据包,所以NAT会在其表中创建一个端口映射条目几分钟.当数据包从Internet到达NAT /路由器时,它会查询该表.当响应从STUN服务器的IP:端口返回时,NAT能够根据上表中的"远程"字段将其转发到NAT后面的计算机.
但是您和希望从中接收数据的"其他公共机器"之间没有端口映射.假设该另一台机器的IP地址是2.4.6.8并且它正在尝试从它的本地端口8888发送.表中的NAT仍然没有任何内容可以将来自2.4.6.8:8888的流量映射到后面的主机NAT.因此,当流量从不在表中的主机到达NAT时,NAT只知道将数据包丢弃在地板上.有一种称为"Cone NAT"的NAT分类可以使用,但这些并不常见.
在您的情况下,有一个简单的解决方法.从STUN服务器获取端口映射后,将另一个数据报从同一本地端口(9999)发送到要从中接收数据的远程主机(和远程端口).远程主机可以简单地忽略此数据报,但它有效地在NAT上创建另一个端口映射条目
------------------------------------------------------------------------------------ || LOCAL IP | LOCAL PORT || EXT PORT || REMOTE IP | REMOTE PORT || ||================================================================================|| || 192.168.1.8 | 9999 || 9999 || 107.23.150.92 | 3478 || || 192.168.1.8 | 9999 || 9999 || 2.4.6.8 | 8888 || ------------------------------------------------------------------------------------这个简单的1字节数据包到2.4.6.8:8888允许NAT将流量从该地址转发回NAT后面的主机.
换句话说,使用您自己的网络流命名法:
My machine:9999 ---->[STUN BINDING REQUEST]--->stun server:3478 My machine:9999 <----[STUN BINDING RESPONSE mapped IP:port]<--- stun server:3478 My machine:9999 [Open socket on port 9999] My machine:9999 ---->[1 byte datagram] -------> 'other:8888' My machine:9999 <---- [UDP to public IP:port obtained in step 2]<----'other:8888'通常,在正常的P2P流中,两个端点都与STUN服务器一起发现它们的端口映射.然后使用另一个服务来交换IP:彼此之间的端口信息.根据您的描述,您可以在程序之间手动交换这些值,这对于测试来说很合适.
如果另一台机器在公共互联网上,从技术上讲,您不需要STUN.第一台机器(在NAT后面)可以直接发送到远程IP和端口,说"向我发送一些数据".远程端只检查此消息的对等地址和端口以决定将其发送回的位置.端口映射已创建.一些RTSP客户端假设服务器是公共的
关于套接字NAT遍历的基础知识的答案就在这里.
我碰巧认识了STUNTMAN的开发者.他是一个相当好的人,外表漂亮,非常聪明.他们还说他和我看起来相似,并且与我们的名字几乎完全相同.如果您对STUN和NAT遍历有疑问,可以随时直接给他发邮件.