socat TCP 服务器双向使用睡眠,非交互式客户端无响应返回。服务器报告:I/O 错误

socat TCP 服务器双向使用睡眠,非交互式客户端无响应返回。服务器报告:I/O 错误

我有以下 TCP 服务器:

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

当我执行(交互模式)时:

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

3 秒后它将返回“OK”(正如预期的那样)

但是,我需要以非交互式的方式进行:

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

但它立即返回而没有响应,并且服务器在 3 秒后报告echo: I/O error(因为客户端不再连接)。

如果我从服务器上删除“sleep 3”,它可以正常工作,但我需要“sleep”才能工作(因为我实际上正在执行一个可能处于睡眠状态的命令,直到它从另一个服务器收到一些响应)。

如何修复?

  • 使用 Ubuntu 22.04
  • 它不需要socat作为客户端使用
  • 最终服务器和客户端将位于不同的服务器上。

答案1

Socat 适用于半关闭套接字。这意味着,当它在一个地址(在您的情况下为 TCP 连接)上收到 EOF(关闭)时,它会关闭第二个地址的写入通道,默认情况下只给它 0.5 秒的时间,直到它完全关闭连接。

因此,即使在交互模式下,如果您在 3 秒内按下 ^D,也会出现 I/O 错误。

可能的解决方案包括:

推迟客户端的 EOF:

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

或者增加两个进程的半关闭超时时间:

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)

答案2

使用nc效果符合预期:

echo "message" | nc localhost 10000

如果有人可以解释为什么socat不一样或者如何使它工作socat,我会接受这个答案。

相关内容