1

I have the following TCP server:

socat TCP-LISTEN:10000,fork,reuseaddr SYSTEM:'read -r msg && sleep 3 && echo "OK"'

When I execute (interactive mode):

socat - TCP:localhost:10000
> some text here [ENTER]

It will return "OK" after 3 seconds (as expected)

However, I need to do it non-interactive:

response=$(echo "some text" | socat - TCP:localhost:10000)

But it returns immediately without response and the server reports after 3 seconds echo: I/O error (as the client is no longer connected).

If I remove "sleep 3" from the server, it works fine, but I need the "sleep" to work (as I'm actually executing a command that may sleep until it gets some response from another server).

How can it be fixed?

  • Using Ubuntu 22.04
  • It doesn't need to use socat as client
  • Ultimately the server and the client will be on different servers.

2 Answers 2

1

Socat works with half close of sockets. That means, when it receives EOF (shutdown) on one address (in your case the TCP connection) it shuts down the write channel of the second address and gives it per default only 0.5 seconds until it closes the connection completely.

Thus you can get the I/O error even in interactive mode when you press ^D before the 3s have passed.

Possible solutions are:

Defer EOF on client:

response=$( { echo "some text"; sleep 4; } | socat - TCP:localhost:10000)

Or increase half close timeout on both processes:

socat -t 3.1 TCP-LISTEN:10000,fork,reuseaddr SYSTEM:'read -r msg && sleep 3 && echo "OK"'

response=$(echo "some text" | socat -t 3.1 - TCP:localhost:10000)
1
  • It works. So in summary, I needed to add -t NUM for both (client and server) in order this to work. Thank you!
    – lepe
    Commented Feb 22, 2023 at 9:28
0

Using nc works as expected:

echo "message" | nc localhost 10000

If someone can explain why socat doesn't work the same or how to make it work with socat, I will accept that answer.

You must log in to answer this question.

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