Search code examples
socat

using socat to multiplex incoming tcp connection


An external data provider makes a tcp connection to one of our servers.

I would like to use socat to 'multiplex' the incoming data so that multiple programs can receive data sent from the external data provider.

socat -u TCP4-LISTEN:42000,reuseaddr,fork OPEN:/home/me/my.log,creat,append

happily accepts incoming data and puts it into a file.

What I'd like to do is something that will allow local programs to connect to a TCP port and begin to receive data that arrives from connections to the external port. I tried

socat -u TCP4-LISTEN:42000,reuseaddr,fork TCP4-LISTEN:43000,reuseaddr 

but that doesn't work. I haven't been able to find any examples in the socat doco that seem relevant to back to back TCP servers.

Can someone point me in the right direction?


Solution

  • With Bash process-substitution

    Multiplexing from the shell can in general be achieved with coreutils tee and Bash process-substitution. So for example to have the socat-stream multiplexed to multiple pipelines do something like this:

    socat -u tcp-l:42000,fork,reuseaddr system:'bash -c \"tee >(sed s/foo/bar/ > a) >(cat > b) > /dev/null\"'
    

    Now if you send foobar to the server:

    socat - tcp:localhost:42000 <<<fobar
    

    Files a and b will contain:

    a

    barbar

    b

    foobar

    With named pipes

    If the pipelines are complicated and/or you want to avoid using Bash, you can use named pipes to improve readability and portability:

    mkfifo x y
    

    Create the reader processes:

    sed s/foo/bar/ x > a &
    cat y > b &
    

    Start the server:

    socat -u tcp-l:42000,fork,reuseaddr system:'tee x y > /dev/null'
    

    Again, send foobar to the server:

    echo foobar |  socat - tcp:localhost:42000
    

    And the result is the same as in the above.