perl - stdin 上的 socat 阻塞

标签 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查过)。

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

我做错了什么?

更新: 感谢有关 cat 和 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>>/dev/null 部分是因为 AIX 提示无效计数器(与超时命令相关)。

最佳答案

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

关于perl - stdin 上的 socat 阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14792621/

相关文章:

java - 使用 SSL 证书触发器运行 Tomcat 服务器无法找到或加载主类 cert.pkcs12

http - 如何在 Laravel 4 中将一条路由重定向到 HTTPS 而将所有其他路由重定向到 HTTP?

perl - 在 perl 中使运行时变量名称成为全局变量

Perl 使用 qx 中的 find

linux - satement "export variable=lib:/dev/input/event0"中的运算符冒号在 linux 环境中是什么意思?

terminal - 须藤 : port: command not found

node.js - AWS beanstalk 应用程序 https 配置不起作用

Perl:检查是否设置了环境变量

perl - 如何确定字符串的字符集?

linux - 当命令使用 EOF 变量时删除 BASH 中命令的输出