在stdin上阻止socat

时间:2013-02-09 23:03:06

标签: perl bash ssl aix socat

我在AIX主机上有一个bash脚本,myscript.sh:

MODE="$1"
if [ "$MODE" == "start" ]; then
    socat -T100 -lf $LOGF -d -d -d -x TCP4-LISTEN:$LISTENINGPORT,bind=$LISTENINGADDR,reuseaddr,fork EXEC:"$0 proxy" &
    PID=$!
    echo $PID > $PIDFILE
    echo "$0 $MODE started (pid=$PID)"

elif [ "$MODE" == "proxy" ]; then
    cat - > $TMPFILE
    # process $TMPFILE before the SSL connection.
    cat $TMPFILE | socat -T 100 -lf $LOGF -d - OPENSSL:$HOST
    rm -f $TMPFILE

我跑步时一切都很好:

$ cat somefile | myscript.sh proxy | xxd

当我使用测试脚本连接到socat监听器时问题出现了:

my $file = $ARGV[0];
my $fsize = -s $file;
my $socket = IO::Socket::INET->new("127.0.0.1:$port")
    or die "Couldn't connect to remote host: $!";
$socket->autoflush(1);
binmode($socket);
open (FILE,$file);
binmode(FILE);
my $buffer ;
while(sysread(FILE, $buffer, $blocksize)) {
    print $socket $buffer ;
}
print "sent\n" ;
close (FILE) ;

my $answer = <$socket>;
if (defined($answer)) {
    print $answer; # never reached
print "...\n" ;
} else {
    die "connection reset by peer\n";
}

在myscript.sh中,它阻止了这一行:

cat - > $TMPFILE

在测试脚本中,它会阻止该行:

my $answer = <$socket>;

此时,socat监听器已收到数据(使用tcpdump检查)。

但是,当我 Ctrl + c 在socat超时之前的测试脚本时,数据将通过管道(即最终联系SSL服务器)。 / p>

我做错了什么?

更新: 感谢关于猫和EOF的提示。目前,我一直在解决这个问题:

timeout 0.2 cat -u - > $TMPFILE 2>>/dev/null
# process $TMPFILE before the SSL connection.
cat $TMPFILE | socat -T 100 -lf $LOGF -d - OPENSSL:$HOST

它很丑,浪费0.2秒,我希望找到更好的解决方案。 但它现在完成了这项工作。 2&gt;&gt; / dev / null部分是因为AIX抱怨计数器无效(与超时命令有关)。

1 个答案:

答案 0 :(得分:1)

我首先想到的是,您尝试使用cat -<STDIN>接收的数据中没有换行符。默认行为中的两个命令一旦有换行符或者文件描述符的缓冲区已满(Linux中默认为4KB),就会返回数据。