Search code examples
linuxsocketsserverstdoutsocat

Redirect linux process stdout to multiple incoming tcp connections


I have a worker process than produces its output onto the stdout pipe.

I would now want to have a service that echoes the stdout of this process to multiple incoming tcp peer connections.

In other words, I want to

  • redirect stdout of a process to a tcp "server" port of the local machine
  • ... so that this tcp port can accept multiple incoming tcp connections
  • ... and relay the stdout contents to all of these incoming connections

The stdin pipe can be ignored.

Question accordingly: Can I achieve this with some existing command line utility, or do I need to write a repeater tool myself e.g. with Python?


I tested using socat and that can serve part of the need, but not in full:

  • socat can redirect stdout to a tcp port and it can accept incoming connections from multiple peer hosts
  • however, socat doesn't echo the stdout stream data to all connections in full, but each connection receive partial stdout data in seemingly random way.

For reference, this is how I tested using socat:

An oneliner bash dummy example that serves updating round N echo entry to port 8080:

for i in {0..10000}; do echo "round ${i}"; sleep 1; done | socat - TCP-LISTEN:8080,fork,reuseaddr

If listening this example dummy stream with two nc localhost 8080 peer connections, both peers receive some of the stdout stream but neither receive all:

Connection 1 receives:
round 1
round 2
round 4
round 7

Connection 2 receives:
round 3
round 5
round 6
round 8

Expectation is that both connections would receive all the 'round 1, round 2, round 3 ...' etc entries.


Solution

  • Socat 1.8 distribution contains the script socat-mux.sh for use on Linux that should do what you need:

    for i in {0..10000}; do
      echo "round ${i}"
      sleep 1
    done | socat-mux.sh TCP-LISTEN:8080 STDIN
    

    Now connect with TCP clients, they should receive the data.

    Please note that this script uses broadcasts on loopback, so any local users might read along.