netcat 可以阻止发送方吗?

Can netcat block on sending side?

在使用命名管道生成健壮的消息传递系统失败后,我尝试使用 netcat。我的接收方将是一个小脚本,它使用 netcat 监听一个端口,产生一个新的监听器并根据接收到的消息执行一个脚本:

# jh_listen.sh
message=$(netcat -l 5555)
nohup jh_listen.sh >/dev/null 2>&1 &
cmd=${message%% *}
parms=${message#* }
nohup ${cmd} ${parms} >/dev/null 2>&1 &

在发送方,它不会比

更复杂

echo "<command> <parms>" | netcat host 5555

我的问题是在监听器关闭连接和新监听器启动之间会有一个短暂的间隔。如果侦听进程未收到消息,通过 netcat 的回显立即结束,什么也不做,因此我有可能丢失消息。是否有可能在发送数据时让 netcat 阻塞直到收到数据?我试过 -q 和 -w 但都没有达到我想要的效果。消息速率会很高并且来自多个主机,因此如果消息发送者在其消息被消耗之前无法阻止,则丢失消息的可能性很高。

附加信息

为了解决发件人不阻塞的问题,我尝试使用

为上述侦听器实现一个可靠的发件人
msgno=1

while [[ true ]]; do
    rc=-1
    retrycount=0

    while [[ ${rc} -ne 0 ]]; do
        echo "<command> <parms> ${msgno} ${retrycount}" | netcat host 5555"
        rc=$?
        echo "<command> <parms> ${msgno} ${retrycount}" >> local.log
        ((retrycount++))
    done
    ((msgno++))
done

虽然我找不到 netcat 退出代码的列表,但如果可以建立连接,它似乎只能以 0 退出。我在作者端的 local.log 中看到的是我所期望的;每次发送后 msgno 都会增加,如果无法发送,则重试计数会偶尔增加。在接收端,我偶尔会在 msgno 序列中收到空消息 and/or 间隙。除了 netcat 有时似乎会丢失 stdin,有时即使它没有发送消息也会以 0 退出,我无法解释。大多数时候它似乎工作正常但还不够好;我需要保证消息能够通过。

不是您问题的直接答案,但是如果您可以使用 socat 而不是 netcat,您可以这样做:

jh_listen.sh:

#/bin/bash
socat TCP4-LISTEN:5555,fork EXEC:./jh_exec.sh

jh_exec.sh:

#/bin/bash
cmd=$(cat -)
exec ${cmd}

在发送端你会做这样的事情:

echo "touch foo" | socat - TCP4:hostname:5555

通过上述设置 jh_listen.sh 将持续侦听端口 5555,并且对于建立的每个连接,它都会派生一个子进程 jh_exec.sh 来处理它。这基本上是一个分叉套接字服务器设置。