【问题标题】:Handle unreachable UDP ports with Java sockets使用 Java 套接字处理无法访问的 UDP 端口
【发布时间】:2011-11-14 11:06:03
【问题描述】:

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

但是,由于不使用 connect(),我失去了 DatagramSocket 对不可达端口的 ICMP 通知做出反应的能力,如果其中一个客户端死亡并且没有机会正确注销服务器。

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

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

【问题讨论】:

    标签: java networking udp datagram


    【解决方案1】:

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

    但是,如果您需要 UDP,我建议您的客户端发送心跳,以便发布者可以使停止发送的订阅者超时。我假设您不需要可靠的连接,但订阅者将数据包发送回发布者仍然值得。

    【讨论】:

    • 我不想要可靠的通信,但我也不想用(对他们而言)毫无意义的流量来淹没无辜的用户;)我可能会选择心跳选项。
    • 如果您有智能路由器,它们只会将 UDP 流量转发到正在监听该流量的服务器。它确实浪费了服务器上的资源。
    • 我担心的不是服务器(它只会收到非常小的新用户偶尔的请求)——可能是用户可能会获得不必要的数据。我的应用程序是音频流,如果没有从服务器正确注销,客户端可能会崩溃或被强制关闭。我看不出我和用户之间的路由器如何将这种情况与用户只是继续监听的情况区分开来(除了路由器是一个状态防火墙,它会考虑来自用户主机的 ICMP 消息)。跨度>
    • 应用程序只有在监听数据时才会接收到不必要的数据。由于您有点对点,因此发送到特定的 IP 和端口是有意义的,在这种情况下,PC 将无法获取它不应该获取的数据。
    • 我知道 UDP 和套接字是如何工作的。我的服务器正在向 IP/端口列表发送数据;当客户端发送“连接”或“断开”数据包时,该列表会更新。但是,客户端可能会突然断开连接,并且“断开连接”数据包永远不会到达我的服务器。客户端一直运行的IP会收到很多不必要的包;我想避免这种情况。
    【解决方案2】:

    它只被连接的 UDP 套接字抛出的原因是它在“C”级别是如何工作的,而 that 的原因是,作为异步,你没有其他方法可以告诉它是哪个目标地址引起的,因为您在“C”级别所拥有的只是errno,而不是 ICMP 消息本身的内容。因此,要“恢复行为”,您确实需要为每个客户端连接一个套接字。如果这不切实际,您将只需要依赖应用程序 ACK 的存在与否。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-06
      • 1970-01-01
      • 2010-10-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多