免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 17493 | 回复: 17
打印 上一主题 下一主题

[技术动态] 外网服务器向内网发送udp数据的问题 [复制链接]

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-05-08 13:19 |只看该作者 |倒序浏览
本帖最后由 群雄逐鹿中原 于 2014-05-08 13:23 编辑

网络是这样的
1. client位于局域网内,经路由器连接到外网
2. server直接连接在外网上

程序步骤:
1. client 监听33333 udp端口
2. server 监听22222 udp端口
3. client 绑定33333端口,发送udp数据包到 server的22222端口
4. server收到数据后,向 “它看到的client ip和端口" 发回数据
    这里, “它看到的client ip和端口",是NAT转换后的ip和端口。
5. client收到server发回的数据

问题:
自己用路由器架设网络,这样是可以发回的。

但是我将server放到真正的公网上的服务器,
只能接收到client发送的数据,数据无法发回到client。

大家帮我看看,是程序有问题,还是公网服务器的网络有问题。

程序如下,简单起见,不用C写了,用nodejs模拟了下

server代码

  1. var dgram = require('dgram');

  2. var socket = dgram.createSocket('udp4');
  3. socket.on('message', function (message, remote) {
  4.         //发送回应
  5.         console.log('client ip:' + remote.address + ', port:' + remote.port +', message:' + message);
  6.         var message = new Buffer("hello, client!");
  7.         socket.send(message, 0, message.length, remote.port, remote.address);
  8. });

  9. //监听端口
  10. socket.bind(22222);
复制代码
client代码

  1. var dgram = require('dgram');

  2. var socket = dgram.createSocket('udp4');

  3. socket.on('message', function (message, remote) {
  4.         //显示server发回的消息
  5.         console.log('server ip:' + remote.address + ', port:' + remote.port +', message:' + message);
  6. });

  7. //监听端口
  8. socket.bind(33333);

  9. //发送消息
  10. function send(server){
  11.         var message = new Buffer("hello, server!");
  12.         socket.send(message, 0, message.length, 22222, server, function(){
  13.                 //1秒后再次发送
  14.                 setTimeout(function(){
  15.                         send(server);
  16.                 }, 1000);
  17.         });
  18. };

  19. //send("127.0.0.1");
  20. //假设公网服务器为public.server.com
  21. send("public.server.com");

复制代码

论坛徽章:
59
2015年亚洲杯之约旦
日期:2015-01-27 21:27:392015年亚洲杯之日本
日期:2015-02-06 22:09:41拜羊年徽章
日期:2015-03-03 16:15:432015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015元宵节徽章
日期:2015-03-06 15:50:392015年亚洲杯之阿联酋
日期:2015-03-19 17:39:302015年亚洲杯之中国
日期:2015-03-23 18:52:23巳蛇
日期:2014-12-14 22:44:03双子座
日期:2014-12-10 21:39:16处女座
日期:2014-12-02 08:03:17天蝎座
日期:2014-07-21 19:08:47
2 [报告]
发表于 2014-05-08 13:51 |只看该作者
Nodejs看得半懂,
好像没问题的样子。
只是为什么client要bind呢?
只要服务器是SendTo到“NAT转换后的ip和端口”就没问题才到。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
3 [报告]
发表于 2014-05-08 13:54 |只看该作者
folklore 发表于 2014-05-08 13:51
Nodejs看得半懂,
好像没问题的样子。
只是为什么client要bind呢?


绑定 “源端口” 为固定值,
这样保证client发出数据的 “源端口” 和监听的端口一样。

于是server向nat的转换端口发送数据,经nat转换后,会发送到client的  “源端口” 。
因为 “源端口” 和监听的端口一样,就能正确收到数据。

论坛徽章:
8
CU大牛徽章
日期:2013-04-17 10:59:39CU大牛徽章
日期:2013-04-17 11:01:45CU大牛徽章
日期:2013-04-17 11:02:15CU大牛徽章
日期:2013-04-17 11:02:36CU大牛徽章
日期:2013-04-17 11:02:58技术图书徽章
日期:2013-12-04 10:48:50酉鸡
日期:2014-01-03 10:32:30辰龙
日期:2014-03-06 15:04:07
4 [报告]
发表于 2014-05-08 14:43 |只看该作者
之前也这样做过,平常没有任何问题。

不过,偶尔也出现过客户端收不到包问题。从服务器机房路由器、本地网络路由器抓包,发现数据包正常发出去了,然后也正常回来了;只是本地路由器把包转发进内网后,那些包就神秘的消失了……

后来又发现,那些数据包并没有消失,而是在内网不知哪里乱窜,大约5分钟后才能传到客户机。这种状况偶尔甚至连在公司内部不同子网间传输数据都会出现。

公司网络状况较为复杂,很多人在上面乱搭服务器/乱做各种实验。总之是无从下手了。


这种状况一般持续一天左右,之后就消失掉;然后说不定哪天谁又瞎搞,就再次出现。
奇怪的是tcp链接通常却不会受到影响(但上周也出现了,整整一周上网困难,打开google首页都要刷新N次。traceroute发现数据包经常[但不是全部]会绕到内网某几个ip走一遭……不知道又是哪个神人在瞎搞什么)。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
5 [报告]
发表于 2014-05-08 15:06 |只看该作者
回复 4# shan_ghost

开始也怀疑网络问题。

然后我换了两个vps主机当服务器,一个香港的,一个国内的。
局域网客户端也用过两个,一个电信(家里的网络),一个联通(公司的网络),
均无法由服务器发回到局域网内。

但是我自己用个路由器组建网络实验,却是成功的,非常的奇怪。

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
6 [报告]
发表于 2014-05-08 15:22 |只看该作者
群雄逐鹿中原 发表于 2014-05-08 15:06
回复 4# shan_ghost

开始也怀疑网络问题。


TTL太小了?

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
7 [报告]
发表于 2014-05-08 15:33 |只看该作者
hellioncu 发表于 2014-05-08 15:22
TTL太小了?


好像不是。ttl设到250还是不行。
并且一个方向能发。

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
8 [报告]
发表于 2014-05-08 15:43 |只看该作者
群雄逐鹿中原 发表于 2014-05-08 15:33
好像不是。ttl设到250还是不行。
并且一个方向能发。


那大概中间的NAT服务器不支持UDP吧

论坛徽章:
8
CU大牛徽章
日期:2013-04-17 10:59:39CU大牛徽章
日期:2013-04-17 11:01:45CU大牛徽章
日期:2013-04-17 11:02:15CU大牛徽章
日期:2013-04-17 11:02:36CU大牛徽章
日期:2013-04-17 11:02:58技术图书徽章
日期:2013-12-04 10:48:50酉鸡
日期:2014-01-03 10:32:30辰龙
日期:2014-03-06 15:04:07
9 [报告]
发表于 2014-05-08 16:05 |只看该作者
群雄逐鹿中原 发表于 2014-05-08 15:33
好像不是。ttl设到250还是不行。
并且一个方向能发。


一个方向……

能登录路由器吗?用tcpdump看看……

我之前遇到的问题,现象上也是一个方向能发,另一方向不通。
后来登录到各个路由上用tcpdump观察,发现其实从服务端到局域网路由是立即到达的;然后局域网路由向内网转发也是立即出现;但转发之后那些包就不知去向了。
要延迟几分钟之后,外网回来的包才能走到客户端。

论坛徽章:
1
戌狗
日期:2014-03-04 13:31:12
10 [报告]
发表于 2014-05-08 17:29 |只看该作者
你服务器的代码的socket地址结构是如何设置的?像这种需要NAT的,如果是INADDR_ANY,通常就不行,需要绑定客户端指定连接的IP。
另外根据NAT的类型不同,对服务器的发送端口也有一定要求,实在不行,服务器的接收端口和发送端口搞成一样的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP