UDP穿透NAT打洞问题

花花呀123456 2008-07-25 12:29:36
打洞理论是这么说的:如果client A 想要向client B发送一个消息,那么不能直接发送,否则会被NAT拦截。必须通知服务器给client B 发送一个通知,通知client B 向client A的方向打洞,那么以后client A就可以直接跟client B联系了。

网上找到的一个解释:
1. Client A向Server发一个UDP包,Server收到后,将发送方的IP地址和UDP端口(NAT A向

Server发送UDP包的端口,而不是Client A的4000端口)通知Client B。之后Client B就需要开始

向这个IP地址和UDP端口发送UDP包了。当然,在下面第2步还未完成之前,Client B向这个IP地址和

UDP端口发送的所有UDP包都会被NAT A丢弃。

2. Client A向NAT B的地址和任意端口发一个包, 发送这个包没有其他目的,只是为了让NAT

A认为从NAT B发送来的UDP包是安全的而已。



我有一个疑问:就是为什么client A直接向client B发送消息会被NAT拦截,但是clinet B向cilent A发送的打洞消息就不会被client A 的NAT拦截呢???

下面是我的想法:
难道是这个client B 给client A 的打洞消息也会被client A 的NAT拦截,但是它的目的已经达到了,就是即使被拦截了,也已经打出了一个洞,从此以后,client A 给client B的消息可以直接发送了。
但是我自己仔细想想不太可能,因为client B给client A 发送的打洞消息被拦截,那么就没有到达client A的这台内网主机,也就不可能在client A的NAT中有这个端口映射,没有端口映射,通过NAT后的clinet A直接发送给clinet B的消息就会加上一个client B 所不知道的外网IP+端口号,对于这个client B的NAT 肯定会拦截。

难道NAT只认IP,不认端口;如果clinet B给client A 的外网IP发过打洞消息(即使这个消息被拦截),那么以后通过这个client A的外网发给 client A的消息都不会被拦截;

但是,我在一个帖子上面看到,NAT是认IP+端口的,那个人换了一个socket ,因为不同socket绑定的不同的服务器端口,所以他用 socket A接收 client 的请求,用socket B去回复client 的时候,client 不能收到消息,也就是说socket B发出的消息不能达到位于NAT后面的client。而如果他用socket A 接收,用socket A回复的话,可以穿过NAT到达client 主机。
这个说明,NAT是认IP,又认端口的。



另外,我自己按照1,2所说的写了自己的代码,但是我是server.client A ,client B,三者同时运行在自己的一台机器上面,我的机器是个内网主机,按照上面的说明,我的client A与clinetB 没法通讯。。。。。

知道内网主机不能做server,因为client不能连接到server,但是我的是可以连接上的(貌似是通过模拟的吧,我的server IP地址就是用的内网IP 192.168.0.X),还有就是知道 有些NAT不支持 “内网环回”(貌似这个说法),就是2个clinet A与clinet B不能位于同一个NAT下面,我不知道我的client A 与client B不能通讯的原因是什么:
1.是由于我的打洞做法错误
2.由于不支持 “内网环回”


如果是原因2,那么说明我的打洞做法是正确的,但是为什么这么打洞是正确 的,我已经说了我的理解是这样打洞是行不通的,那么请告诉我为什么这样打洞是正确的。。。。。。


自己想了很久,还是不知道怎么回事,请有经验的高手跟前辈们指教。本人一向很大方分数。散发100,如果答案满意,可以再加。


...全文
897 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
rickys2080 2011-07-20
  • 打赏
  • 举报
回复
同问啊,最近也是这个问题,打洞,通信
rickys2080 2011-07-20
  • 打赏
  • 举报
回复
+++++++++++++++
sichuanwww 2011-05-16
  • 打赏
  • 举报
回复
QQ是怎么实现的呢?
swift19221 2011-03-29
  • 打赏
  • 举报
回复
我安装流程走,始终没有成功过
hellboy9527 2010-07-13
  • 打赏
  • 举报
回复
mark
nokianasty 2010-06-05
  • 打赏
  • 举报
回复
mark
geniusdim 2010-03-30
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 cnzdgs 的回复:]
LZ应该先了解一下NAT的原理,再尝试“打洞”。NAT大概分4种类型,最常见的工作原理大致是:当内网主机使用一个端口向外发送数据时,NAT在公网分配一个端口,与该主机端口向关联,此后该主机端口发出的数据都用该公网端口向外发送,该公网端口收到的数据都转发给该主机端口。
“打洞”要借助公网Server有两点原因:一是要让NAT给主机分配端口建立关联;二是要获得主机的公网IP和端口号。这样才能与该主机……
[/Quote]
“当内网主机使用一个端口向外发送数据时,NAT在公网分配一个端口,与该主机端口向关联,此后该主机端口发出的数据都用该公网端口向外发送,该公网端口收到的数据都转发给该主机端口。”
内网主机使用的端口是不是要端口映射啊???
jingkingsoft 2008-09-26
  • 打赏
  • 举报
回复
3的情况估计连服务器都会比较麻烦了,一个UDP Socket只能同时发送和接收。如果服务端要提高效率,采用一个SOCKET专事接收,多个SOCKET一起发送的话,发送的端口也是不一样的,在客户端NAT看来,发送的SOCKET也是“IP正确,端口错误”的。
不知道认远程发送端口的NAT占得比例多大。
JonathanS666 2008-09-01
  • 打赏
  • 举报
回复
顺便问一句,如何查看路由器的NAT表?
zhucz333 2008-09-01
  • 打赏
  • 举报
回复
mark
JonathanS666 2008-09-01
  • 打赏
  • 举报
回复
看看电驴的代码
yutianxing 2008-08-29
  • 打赏
  • 举报
回复
想了解这方面的知识。
hurryboylqs 2008-08-27
  • 打赏
  • 举报
回复
得到NAT类型就好办了,因为这个通信端口大部分是经常会变动的,但变动基本都是有规律的,NAT类型会告诉你这个规律
Wenxy1 2008-08-27
  • 打赏
  • 举报
回复
穿透NAT有几种情形:(假设有两台计算机:x,y)

1 x,y只有其中一个是私有IP(i.e. 有一台机器位于内网)。
2 x,y两都是私有IP(i.e. 两台机器都位于内网)。
laibach0304 2008-08-19
  • 打赏
  • 举报
回复
里面有一个时序的问题
不一定是哪一个包被nat拦截
monkchen 2008-08-19
  • 打赏
  • 举报
回复
网上找到的一个解释:
1. Client A向Server发一个UDP包,Server收到后,将发送方的IP地址和UDP端口(NAT A向

Server发送UDP包的端口,而不是Client A的4000端口)通知Client B。之后Client B就需要开始

向这个IP地址和UDP端口发送UDP包了。当然,在下面第2步还未完成之前,Client B向这个IP地址和

UDP端口发送的所有UDP包都会被NAT A丢弃。

2. Client A向NAT B的地址和任意端口发一个包, 发送这个包没有其他目的,只是为了让NAT

A认为从NAT B发送来的UDP包是安全的而已。
------------------------------------------------------------------------------------
我的成功做法如下:
通信的参与者有三方,分别是P2PServer, PeerServer, PeerClient; 我的业务流程是这样的,PeerServer作为视频源而存在,PeerClient向其请求视频数据然后播放,
PeerServer启动或登录时向P2PServer发送数据包,P2PServer收到的addr则是PeerServer经nat后的ip和端口, 事实上这个数据包如果发送成功,则PeerSever的udp洞已经打开了,P2PServer和PeerServer的会话建立成功,只要每隔一段时间(保险一点可以取30秒)向P2PServer服务器发送心跳包,那么这个会话就不会结束!

数据包含有改PeerSever的唯一标识ID, P2PServer可以维护一个PeerServer的信息列表(一下简称会话列表),可以用结构体数组来实现。
当然,PeerServer也不能保证24小时在线,可能因为关机,重启,关闭软件或者包发送失败等, P2PServer并不总是能收到心跳包,所以P2PServer也要定时检验会话列表,如果发现某个会话的上次心跳时间距离现在已经超过两分钟,则视为其PeerServer掉线,将该会话信息删除

这时候PeerClient只要知道PeerServer经NAT后的IP和Port就能直接和PeerServer进行通信, 怎么知道? 当然是向P2Pserver查询了!

scq2099yt 2008-08-19
  • 打赏
  • 举报
回复
up
zhb1190 2008-08-19
  • 打赏
  • 举报
回复
学习
花花呀123456 2008-08-03
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 cnzdgs 的回复:]
2、Server根据外网IP可以判断两台Client是否在同一内网…
[/Quote]


判断出来以后,怎么样去取得内网IP是个问题啊。。。小弟第一次开发网络程序,请多多指教。。。


cnzdgs 2008-07-25
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 tangaowen 的回复:]
再问一个问题:
1.怎样将内网主机作为一个公网主机一样做server?
2.如果是在同一个局域网的话,可以直接用内网IP地址通讯,这样就可以绕过“内网环回”问题。现在我的问题是,如果client A与client B在同一个局域网内部,怎样获得他们的内网IP,因为我的server获得的是他们外网IP,只是他们的端口不同而已。
[/Quote]
1、设置NAT端口映射。
2、Server根据外网IP可以判断两台Client是否在同一内网,Client可以自己取出内网IP和端口发包告诉Server。
加载更多回复(7)

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧