使用 socat 从 Unix 域套接字编写脚本先写后读

使用 socat 从 Unix 域套接字编写脚本先写后读

我有一个简单的服务器监听 Unix 域套接字(在 CentOS 机器上,以防万一)。当我向套接字发送命令“DATE”时,它会写回一条欢迎消息,然后写回“2015 年 4 月 15 日”。我可以使用以下命令手动执行此操作:

socat - UNIX-CONNECT:/tmp/server.sock

但我现在想编写它的脚本。我可以通过将 echo 的输出管道传输到上面来将 DATE 命令发送到套接字,但随后 socat 仅返回欢迎消息。我不确定 socat 是否只返回前两行,或者在关闭套接字之前等待一段安静的时间,或者什么。例如:

echo "DATE" | socat - UNIX-CONNECT:/tmp/server.sock

如何让 socat 在断开连接之前捕获整个响应?我尝试过 -t 和 -T 参数让它等待 5 秒,但这没有效果,socat 立即返回。

答案1

在:

echo "DATE" | socat - UNIX-CONNECT:/tmp/server.sock

echowritesecho\n然后退出,关闭管道的写入端。

这会导致 eof 出现在-地址的读取端。然后socat关闭 unix 域套接字的“发送”端,并且只要在 0.5 秒内没有看到任何从套接字从另一个方向传入的内容就终止。

可以通过该选项增加 0.5 秒的超时时间-t。所以:

echo DATE | socat -t 300 - UNIX-CONNECT:/tmp/server.sock

socat将等待 5 分钟以获取日期回复或服务器关闭其连接的发送端,以先到者为准。

如果您的服务器在客户端关闭其发送端时中止,您可以保持客户端(管道左侧echo:)运行,直到服务器终止连接(假设它在发送回复后立即关闭连接),您可以做类似的事情:

sh -c 'echo "$$"; echo DATA; exec sleep infinity' | {
  IFS= read -r pid
  socat -t0 - UNIX-CONNECT:/tmp/server.sock
  kill -s PIPE "$pid" # terminate the client after the server shuts down
}

或者:

echo DATE | socat -t0 -,ignoreeof UNIX-CONNECT:/tmp/server.sock

(使用 时ignoreeofsocat忽略 eof 并继续尝试每秒读取更多内容。对于管道,eof 之后不会出现任何内容,但这仍然给了我们我们想要的:模拟仍然存在的客户端)。

或者在看到回复后立即终止:

sh -c 'echo "$$"; echo DATA; exec sleep infinity' | {
  IFS= read -r pid
  socat -t0 - UNIX-CONNECT:/tmp/server.sock | {
    IFS= read -r welcome
    IFS= read -r date
    printf '%s\n' "$date"
  }
  kill -s PIPE "$pid" # terminate the client after the reply has been read
}

相关内容