2013-06-26 60 views
3

我有一个基于UDP Netty的服务器。它有一个SimpleChannelUpstreamHandler流水线,我重写了messageReceived方法。Netty - UDP服务器

我现在需要回写一些信息。我只能通过使用来自MessageEvent.getRemoteAddress()的套接字信息和来自MessageEvent.getChannel()的通道来做到这一点。为了能够重复使用这些信息,我保存在一张静态地图中。

这变成MessageEvent.getChannel().write("foo", MessageEvent.getRemoteAddress());

我本来期望是有MessageEvent.getChannel().getRemoteAddress()工作,这是情况并非如此。它总是给我null

  1. 我做错了什么?
  2. 写回来比保留某些成员的频道和远程地址更好吗?

回答

4

当使用UDP(数据报)通道作为服务器通道时,只能将其绑定在本地地址上,并且不建立连接。这就是为什么没有与该频道相关联的远程地址,并且您在致电MessageEvent.getChannel().getRemoteAddress()时总是得到null。这种行为是预期的并且是正确的同一个UDP“服务器”通道处理所有传入的客户端请求。

当使用UDP通道作为客户端通道时,可以通过将通道连接到远程地址来创建“连接”。在这种情况下,通道将有一个配置的远程地址(尽管没有实际的连接),并且调用MessageEvent.getChannel().getRemoteAddress()将返回配置的远程地址。 连接UDP通道可防止用户使用通道将数据发送到通道中配置的远程地址以外的远程地址。试图这样做会引发异常。在UDP中连接客户端通道是可选的,只要保存远程地址,客户端就可以使用只绑定在本地地址上的通道正常工作。

我认为你有两个选择:

  1. 节省了客户端的远程地址与客户端标识与使用“服务器”通道发送的数据。保存频道将不起作用,因为同一频道将用于与所有客户端进行通信。
  2. 为每个客户端创建一个新的连接通道,并使用客户端标识符保存新通道。

我相信第一种方法更好。

2

正如你可能知道UDP是无连接传输。单个通道可以从任何目标地址接收数据并将数据写入任何目标地址。因此,UDP通道没有像TCP通道那样具有关联的远程地址。虽然我认为可以通过netty将UDP通道与特定的远程地址关联起来,但我还没有掌握细节,说实话,我认为从消息事件中获取地址是更好的选择。

这导致你的第二个问题,那就是,你需要将远程地址保存在某个地方。我在Netty中没有做过任何UDP编程,因此我不确定是否需要将远程地址映射到通道对象,或者Netty是否总是返回相同的通道对象。这是值得检查的,因为您可能只需要保持对频道的单一引用。

+0

谢谢!我本来期望的是通过频道获得远程地址供以后使用。如果这不切实际,也许抛出一个不受支持的操作异常会更好。 关于频道引用,我不知道我是否做得对。我期待多个客户端连接,每个客户端都会发送一些数据以及唯一的客户端标识符。我把频道映射到这个唯一的标识符。想法? – thelost

2

1)看看这个UDP upstream handler。要获得发件人的远程地址,您可以使用以下代码SocketAddress remoteAddress = datagramPacket.sender();
2)@johnstlr提到的是正确的,将UDP通道与单个远程地址关联是不正确的。但是,您可以使用并发哈希映射来执行查找,如上面的文件中所示。这个game server实际上使用具有TCP和UDP连接的会话。这使得通过TCP发送可靠数据以及通过UDP发送所有帧数据变得容易。