2

I'm using a Java DatagramSocket to stream data to multiple different clients. As I handle the list of currently registered clients myself, I only bind the socket to the server port and don't connect to any specific client.

However, by not using connect(), I lose the ability of the DatagramSocket to react to ICMP notifications of an unreachable port, which are sent if one of the clients dies and doesn't get the chance to properly unregister with the server.

Is there any way to get that behavior back? I thought of using one DatagramSocket per client, but that doesn't seem to be feasible as they would all have to be bound to the same port on the server (impossible in UDP, as far as I know).

I'm aware that there is no guarantee that my server ever sees the ICMP messages and I'll implement some kind of timeout mechanism to handle that, but reacting to the ICMP messages would allow me to immediately stop transmitting to any host that doesn't have a client running, which seems like a nice thing to do to the streaming client users.

user207421
  • 305,947
  • 44
  • 307
  • 483
lxgr
  • 3,719
  • 7
  • 31
  • 46

2 Answers2

1

If you want reliable point to point connections, I would use TCP.

However if you want UDP, I would suggest your clients send heartbeats so the publisher can timeout subscribers which stop sending. I assume you don't need the connection to be reliable, but it can still be worth the subscribers sending packets back to the publisher.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • 1
    I don't want reliable communication, but I also don't want to flood innocent users with (to them) meaningless traffic ;) I'll probably go with the heartbeat option. – lxgr Nov 14 '11 at 12:24
  • 1
    If you have intelligent routers, they will only forward UDP traffic to servers which are listening to that traffic. It does waste resources on the server. – Peter Lawrey Nov 14 '11 at 13:57
  • It's not the server that I'm worried about (it gets only very small and occasional requests by new users) - it's the users that might get unnecessary data. My application is audio streaming, and the client could possibly crash or be force closed without properly unregistering from the server. I don't see how a router between me and the user could distinguish that case from one where the user simply keeps on listening (except for the router being a stateful firewall that takes the ICMP messages from the user's host into account). – lxgr Nov 14 '11 at 15:23
  • The application will only receive unnecessary data if it is listening to that data. Since you have point to point, it makes sense to send to a specific IP and port, in which case a PC will not get data it should not. – Peter Lawrey Nov 14 '11 at 16:07
  • I'm aware of how UDP and sockets work. My server is sending data to a list of IPs/ports; that list is updated when a client sends a "connect" or "disconnect" packet. However, the client could be abruptly disconnected, and the "disconnect" packet would never reach my server. The IP where the client has been running will get a lot of unnecessary packets; I want to avoid that. – lxgr Nov 14 '11 at 16:23
  • I see now. In that case using a heartbeat is the best approach. However, I personally would just use TCP. ;) – Peter Lawrey Nov 14 '11 at 17:21
  • Thanks, I'll go with the heartbeat! Seems like the most robust solution for UDP. TCP is unfortunately not an option. – lxgr Nov 14 '11 at 22:07
  • @Ixgr, I am curious as to why TCP wouldn't be an option. – Peter Lawrey Nov 15 '11 at 08:10
  • It's a requirement for the application I'm writing - it specifically has to use UDP, even if I'd prefer TCP myself. In fact, I've already done it in TCP, and it worked pretty well. – lxgr Nov 20 '11 at 17:08
0

The reason it's only thrown by connected UDP sockets is that thats how it works at the 'C' level, and the reason for that is that, being asynchronous, there is no other way you could tell which target address caused it, because all you have at the 'C' level is an errno, not the contents of the ICMP message itself. So to 'get the behaviour back' you would indeed need a socket per client, connected. If that's not practical you wil just have to rely on the presence or absence of application ACKs.

user207421
  • 305,947
  • 44
  • 307
  • 483