views:

881

answers:

2

I currently have a small Python script that I'm using to spawn multiple executables, (voice chat servers), and in the next version of the software, the servers have the ability to receive heartbeat signals on the UDP port. (There will be possibly thousands of servers on one machine, ranging from ports 7878 and up)

My problem is that these servers might (read: will) be running on the same machine as my Python script and I had planned on opening a UDP port, and just sending the heartbeat, waiting for the reply, and voila...I could restart servers when/if they weren't responding by killing the task and re-loading the server.

Problem is that I cannot open a UDP port that the server is already using. Is there a way around this? The project lead is implementing the heartbeat still, so I'm sure any suggestions in how the heartbeat system could be implemented would be welcome also. -- This is a pretty generic script though that might apply to other programs so my main focus is still communicating on that UDP port.

+2  A: 

I don't think this is possible. What you'll have to do is have one UDP master program that handles all UDP communication over the one port, and communicates with your servers in another way (UDP on different ports, named pipes, ...)

Wim
It's not possible by definition. One Program per Port is the way UDP (and TCP) work. One program can dispatch to other programs.
S.Lott
You're right, through the OS it's impossible. If you have raw access to the network adapter (through `libpcap` or similar) it would be possible, but not pretty...
Wim
Is there an implementation-way around this, like possibly implementing the heartbeat in a specific way?Maybe I can send a broadcast packet, and have the reply sent to an open port? All servers would get the packet, and could be instructed to reply at 7877 maybe? - The project lead is open to things such as this I suspect.
ThantiK
I suspect multiple executables all trying to reply at the same time on that same port though just runs into the same problem.
ThantiK
IP/UDP broadcast packets are meant to be received by multiple machines, not on multiple ports, so that won't work. Since your script is starting the servers itself, can't it just specify a unique UDP port on the commandline and use that to communicate with the server?
Wim
Each server uses it's own UDP port already - question: Is it possible to have multiple programs on the same computer just SEND on the UDP port? If so I think I answered my own question...if that's the case then I'll just have the project lead implement the heartbeat in such a way that I can specify a reply port. Open a listening port on 7877, then UDP AWAY to all the different ports, and have them all reply to my listener port....Does that sound correct?
ThantiK
I just tested this out with a small python script that just did UDPSock.sendto(data,addr) in a loop, and it seems as if I can just do it the way I described. Thanks a lot for your help WIM, sometimes it helps just to talk things through with someone else and bounce things until your brain sorts it out on its own.
ThantiK
+1  A: 

I'm pretty sure this is possible on Linux; I don't know about other UNIXes.

There are two ways to propagate a file descriptor from one process to another:

  • When a process fork()s, the child inherits all the file descriptors of the parent.
  • A process can send a file descriptor to another process over a "UNIX Domain Socket". See sendmsg() and recvmsg(). In Python, the _multiprocessing extension module will do this for you; see _multiprocessing.sendfd() and _multiprocessing.recvfd().

I haven't experimented with multiple processes listening on UDP sockets. But for TCP, on Linux, if multiple processes all listen on a single TCP socket, one of them will be randomly chosen when a connection comes in. So I suspect Linux does something sensible when multiple processes are all listening on the same UDP socket.

Try it and let us know!

Larry Hastings