2011-11-14 58 views
1

我正在使用Java DatagramSocket将数据传输到多个不同的客户端。当我自己处理当前注册的客户端列表时,我只将套接字绑定到服务器端口,并且不连接到任何特定的客户端。使用Java套接字处理不可达UDP端口

但是,通过不使用connect(),我失去了DatagramSocket对无法访问端口的ICMP通知的响应能力,如果其中一个客户端死亡并且没有机会正确注销服务器。

有没有什么办法让这种行为回来?我想为每个客户端使用一个DatagramSocket,但这似乎并不可行,因为它们都必须绑定到服务器上的相同端口(据我所知,在UDP中是不可能的)。

我知道,我不能保证我的服务器能够看到ICMP消息,我会实现某种超时机制来处理这种情况,但是对ICMP消息的反应将允许我立即停止传输给任何没有运行客户端的主机,这对流媒体客户端用户来说似乎是件好事。

回答

1

如果你想要可靠的点对点连接,我会使用TCP。

但是,如果你想要UDP,我会建议你的客户端发送心跳信号,这样发布者可以超时停止发送的用户。我假设你不需要连接是可靠的,但它仍然值得用户将数据包发送回发布者。

+1

我不希望可靠的沟通,但我也不希望洪水无辜的用户(对他们)毫无意义的交通;) 我可能会去心跳选项。 – lxgr

+1

如果您有智能路由器,他们只会将UDP流量转发到正在监听该流量的服务器。它确实浪费了服务器上的资源。 –

+0

这不是我担心的服务器(它只能得到非常小的,偶尔会被新用户请求) - 这是用户可能会得到不必要的数据。我的应用程序是音频流媒体,客户端可能会崩溃或强制关闭,而无需从服务器正确注销。我没有看到我和用户之间的路由器如何区分这种情况与用户只是继续监听的情况(除了路由器是将用户主机的ICMP消息考虑在内的状态防火墙除外)。 – lxgr

0

它只是被连接的UDP套接字抛出的原因在于它是如何在'C'级别工作的,的原因是,它是异步的,没有其他方式可以告诉哪个目标地址造成了这种情况,因为你在'C'级拥有的只是一个errno,而不是ICMP消息本身的内容。所以要“让行为回来”,你确实需要为每个客户端连接一个套接字。如果这样做不实际,你只能依靠应用程序确认的存在与否。