3

I'm looking for a linux tool to run under fedora that will open a tcp/ip socket for listening, let it connect multiple clients on the same port. Then when one client sends a message relay it to all other clients. Rather not relay it back to the original client, but if it does also relay back to the originating client that's ok. I'm not sure if "relay" is the right term here, maybe if i would have searched for another keyword i would have gotten better results. Just to be clear: there should not be a protocol on top of the socket by the server. If there is going to be a protocol it will be implemented on the client only both in sending and receiving. Further requirement is that reliability is the most important thing, that's why i'm looking for TCP/IP and not UDP. Any other suggestions to make it more reliable are welcome.

Some places i looked for a solution:

https://cr.yp.to/ucspi-tcp/tcpserver.html Spawns different instances of "program" which then still need to communicate to each other, so it's only a partial solution.

TCP Proxy with multiple clients? The solution i'm looking for does not connect to a port first, so doesn't seem suitable.

https://stackoverflow.com/questions/9024227/duplicate-input-unix-stream-to-multiple-tcp-clients-using-socat/11362423 I don't have a process writing to a socket, so doesn't seem suitable.

Even though the questions of the previous two links do not match mine, there are things in there that make me belief that socat could still be an option, but i'm not sure.

9
  • Would socat combined with tee be an option?
    – JdeHaan
    Commented Oct 25, 2016 at 16:24
  • do you imagine a star-like configuration?
    – nrc
    Commented Oct 25, 2016 at 17:59
  • @JdeHaan yes this is an option, unix pipes or fifo's are certainly an option. I don't neccesarily need output to console on the server but i guess it will be useful for debugging.
    – Flip
    Commented Oct 26, 2016 at 8:20
  • @nrc yes, actually i was considering a mesh network too but the scope of this question is star-like configuration only.
    – Flip
    Commented Oct 26, 2016 at 8:20
  • It's a classic real-time chat scenario, have you considered to use a message-oriented middleware like AMPQ? And, if your goal is service reliability on Linux, you should consider the corosync/pacemaker stack.
    – nrc
    Commented Oct 26, 2016 at 16:55

2 Answers 2

1

What about something like:

socat tcp-listen:1234,fork,reuseaddr \
      'system:tail -fn +0 file & cat >> file'
5
  • It works, but there are two downsides. 1. create a huge file on disk 2. resends everything to a client after it has lost connection. Especially 2 it would need some more intelligence to figure out how much update the client needs. I didn't require to resend everything from the past. It's a nice answer so i will upvote but not accept.
    – Flip
    Commented Feb 8, 2017 at 9:14
  • @Flip, you can always change the +0 to 0 if you don't want the past info. Or 10 if you want only the last 10 lines. If the client sends its output straight away upon connecting, you may find that it doesn't get the initial part depending on the timing of the cat and tail initialisation. Commented Feb 8, 2017 at 9:32
  • If you don't care about past data, you could reclaim the space in the file by doing some fallocate -c (if on Linux) (or fallocate -p to avoid invalidating the offsets) here and then. The point is you need to keep enough data for the slowest reader (and think of bad connections that could delay reading for hours), so a file like that is not such a bad idea especially if we're talking huge amounts of data that can't fit in memory. Commented Feb 8, 2017 at 9:40
  • @Flip If you want the client to be able to reconnect and resume downloading from where they left, it's virtually impossible without implementing a protocol where the client tells you where they left upon reconnection as at the other end you can't reliably tell what was successfully delivered to the client last time. Commented Feb 8, 2017 at 9:45
  • Why are these problems not solved on the TCP/IP layer? Why do i need to keep a file around for slow clients when i can keep ethernet frames in buffer for slow clients instead? Ethernet frame (kept for resend) can be cleared when slow client times out. Why does the sender side not control the timeout but the client can keep the connection open for hours?! I don't require the sending of past data that was send before the client connects.
    – Flip
    Commented Feb 8, 2017 at 13:36
0

This will do the trick:

socat tcp-listen:5555,fork,reuseaddr \
'system:
PIPE=$(mktemp -u /tmp/pns_XXX)
mkfifo $PIPE
while read PIPE_MESSAGE<$PIPE; do
  echo $PIPE_MESSAGE
done &
PID=$!
while read CLIENT_MESSAGE; do
  for OTHER_PIPE in $(ls /tmp/pns_*); do
    [ $PIPE != $OTHER_PIPE ] && echo $CLIENT_MESSAGE > $OTHER_PIPE
  done
done
kill $PID
rm $PIPE'

The idea is to create a named pipe for every new connection and then echoing to std output (i.e. send to client) whatever is read from the pipe. Std input (i.e. send by client to server) is read from and whatever is received is echoed to all the named pipes, except the own pipe.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .