udp服务器向内网通讯问题

Jan 23, 2015 at 5:17 AM
按照例子使用了udp功能
内网向服务器发送信息正常,
在服务端MessageReceived事件里通过e.Session向内网发回发信息,内网收不到.
请问是不是还需要格外的"打洞"之类的操作?
Coordinator
Jan 26, 2015 at 3:00 AM
你好,

一般来说当UDP/TCP报文从内网穿过路由器到外网时,路由器上应当自动保持NAT,以保证双向通信的。
我做了测试,也确实是双方都可以收到消息。
测试代码基于Example/UDP,修改了以下一些代码:

MemoryMonitor中:
acceptor.MessageReceived += (s, e) =>
{
    IoBuffer buf = e.Message as IoBuffer;
    if (buf != null)
    {
        Console.WriteLine("New value for {0}: {1}", e.Session.RemoteEndPoint, buf.GetInt64());
        // 返回消息给客户端
        e.Session.Write(IoBuffer.Wrap(System.Text.Encoding.Default.GetBytes("DONE")));
     }
};
MemMonClient中:
connector.MessageReceived += (s, e) =>
{
    IoBuffer buf = e.Message as IoBuffer;
    Console.WriteLine("Session recv... {0}", buf.GetString(System.Text.Encoding.Default));
};
服务端分别放在内网和外网上做了测试,客户端在内网,都是可以接收到返回消息的。
因此,可能是你的环境中路由器的设置不太一样?
Jan 27, 2015 at 11:29 AM
TCP是没有问题的.
路由器是恢复出产设置下,在未有任何设置下QQ类的UDP协议都是正常可用的.
这应该不是路由器问题吧?
另外就是
e.Session.Write(IoBuffer.Wrap(System.Text.Encoding.Default.GetBytes("DONE")));
这个代码不会执行第二次.猜测是因为Write超时未处理?这样的情况下客户端发送给服务器的信息也不会继续正常接收.
Coordinator
Jan 29, 2015 at 7:08 AM
Edited Jan 29, 2015 at 7:12 AM
我使用之前的代码在内网-外网环境中对.NET20和.NET40分别进行了测试,并进行了交叉测试,均可以成功通信。
因此不太清楚是什么原因了。

服务端得到如下的输出:
UDPServer listening on port 18567
Session created...
Session opened...
New value for 114.2**.1*.**:56742: 463756
New value for 114.2**.1*.**:56742: 463756
New value for 114.2**.1*.**:56742: 471948
New value for 114.2**.1*.**:56742: 471948
New value for 114.2**.1*.**:56742: 471948
New value for 114.2**.1*.**:56742: 471948
New value for 114.2**.1*.**:56742: 471948
New value for 114.2**.1*.**:56742: 471948
New value for 114.2**.1*.**:56742: 471948
Session closed...
客户端得到如下的输出:
Session created...
Session opened...
...connected
Session sent...
Session recv... DONE
Session sent...
Session recv... DONE
Session sent...
Session recv... DONE

Write不会超时的,socket只管把报文发送出去,这个操作没有超时选项。
我是按照你说的在服务端MessageReceived事件中向e.Session发回信息,如果 e.Session.Write 不能执行第二次,那说明服务端之后就再也没有收到客户端消息了。
如果是服务端发回消息后才出现通信失败,或许是客户端在接收消息时出错了,网络出错或功能出错?
Jan 31, 2015 at 5:50 AM
Edited Jan 31, 2015 at 6:24 AM
好吧,谢谢!

我发现问题来源的可能性了.我服务器本有3个IP,比如
..***.11
..***.12
..***.13
我一直都是内网向13这个IP发送信息,结果就出现我之前所说的情况(服务器端如同死亡,任何其他信息都不会再进行处理,接收与否也不知道.)
就刚刚我反应过来,只向11这个发送信息,结果一切正常了.
我猜想应该是服务端自动绑定只绑定第一个(如果有多个)IP吧?

这样又来了一个问题了,如果有恶意用户向12或者13发送一条信息,服务端就形容死了.这也挺糟糕的.

就反馈一个这样的问题,希望有帮助,谢谢.
Jan 31, 2015 at 7:53 AM
问题解决了,谢谢.
把IP都Bind就行了.
Coordinator
Feb 4, 2015 at 2:52 AM
很高兴问题解决了,不过关于IP绑定引发的潜在问题,我还有一些疑问。
请问之前是使用 IPAddress.Any 进行Bind的么?
acceptor.Bind(new IPEndPoint(IPAddress.Any, port));
这时绑定的是0.0.0.0,是绑定到所有IP接口的,如果这种情况下会导致某个IP接收消息后服务端出现问题,那有可能是个比较严重的BUG呢。
Feb 4, 2015 at 3:11 PM
是的,在问题未解决之前测试使用的是默认例子里的代码,
就是acceptor.Bind(new IPEndPoint(IPAddress.Any, port));
Coordinator
Feb 5, 2015 at 1:16 AM
谢谢提供信息,我之后测试一下。
Feb 5, 2015 at 6:01 AM
请问下有没有交流群啊什么的.既然是国产的开源应该要多支持.建议在oschina提交哦,让更多的人知道,文档多了,使用的人自然也多了.
Coordinator
Feb 9, 2015 at 8:40 AM
谢谢支持~
OSChina上有发布呢,在这里:http://git.oschina.net/longshine/Mina.NET
不过主库还是在GitHub上,CodePlex和OSChina是备份仓库。
交流群目前还没有呢,CodePlex上的文档也只写了一半,鄙人一个人实在是精力有限……
这个项目已经贡献给了社区,就不再是某一个人的了,欢迎加入共同来发展开源项目~
可以fork项目来提交pull request,或者如果有兴趣的话,也可以成为这个项目的dev噢。
Feb 10, 2015 at 11:15 AM
不单单是指Git在oschina上,还包括项目介绍等,方便大家搜索到,比如.Net项目介绍里.
http://www.oschina.net/project/lang/194/csharp