无法使用socat连接到套接字

Not able to connect to socket using socat

我正在尝试解析 rsyslog 日志。为此,我将所有日志发送到 socat,然后将它们发送到 Unix Domain Socket。该套接字是通过 perl 脚本创建的,该脚本正在侦听该套接字以解析日志。

rsyslog 将所有日志发送到的我的 bash 脚本是

if [ ! `pidof -x log_parser.pl` ] 
  then
./log_parser.pl & 1>&1
fi

if [ -S /tmp/sock ] 
then
/usr/bin/socat -t0 -T0   - UNIX-CONNECT:/tmp/sock 2>> /var/log/socat.log
fi

/tmp/sock 是使用 perl 脚本 log_parser.pl 创建的,即

use IO::Socket::UNIX;

sub socket_create {
    $socket_path = '/tmp/sock';
    unlink($socket_path);

    $listner = IO::Socket::UNIX->new(
       Type   => SOCK_STREAM,
       Local  => $socket_path,
       Listen => SOMAXCONN,
       Blocking => 0,
    )
       or die("Can't create server socket: $!\n");

   $socket = $listner->accept()
      or die("Can't accept connection: $!\n");
   }

   socket_create();
   while(1) {

   chomp($line=<$socket>);
   print "$line\n";
   }

我从 socat 得到这个错误

2015/02/24 11:58:01 socat[4608] E connect(3, AF=1 "/tmp/sock", 11): Connection refused

我不是套接字的拥护者,所以我无法理解这是什么。请帮忙。提前致谢。

主要问题是,当我终止我的 perl 脚本时,bash 脚本会再次调用它并启动它。 实际发生的是 sript 已启动但 socat 未启动而是给出此错误并且永远不会启动。

如果我在尝试使用 socat 之前不 运行 你的 perl 程序,我可以复制你的错误。这对我有用:

1) my_prog.pl:

use strict; 
use warnings; 
use 5.016;
use Data::Dumper;
use IO::Socket::UNIX;

my $socket_path = '/tmp/sock';
unlink $socket_path; 

my $socket = IO::Socket::UNIX->new(
    Local  => $socket_path,
    Type   => SOCK_STREAM,
    Listen => SOMAXCONN,
) or die "Couldn't create socket: $!";

say "Connected to $socket_path...";
my $CONN = $socket->accept()
    or die "Whoops! Failed to open a connection: $!";

{
    local $/ = undef;   #local -> restore previous value when the enclosing scope, delimited by the braces, is exited.
                        #Setting $/ to undef puts file reads in 'slurp mode' => whole file is considered one line.
    my $file = <$CONN>; #Read one line.
    print $file;
}`

2) $ perl my_prog.pl

3) socat -u -v GOPEN:./data.txt UNIX-CONNECT:/tmp/sock

不需要 -u 和 -v 选项:

-u            Uses  unidirectional  mode.  The  first address is only used for
              reading, and the second address is only used for writing  (exam-
              ple).


-v            Writes the transferred data not only to  their  target  streams,
              but  also to stderr. The output format is text with some conver-
              sions for readability, and prefixed with "> " or "< " indicating
              flow directions.

4) 你也可以这样做:

cat data.txt | socat STDIN UNIX-CONNECT:/tmp/sock

cat 命令的标准输出通过管道传输到 socat,然后将 STDIN 列为 socat 的文件之一。

回复评论:

这个 bash 脚本适合我:

#!/usr/bin/env bash

echo 'bash script'

../pperl_programs/my_prog.pl &
sleep 1s

socat GOPEN:./data.txt UNIX-CONNECT:/tmp/sock

在 socat 尝试传输数据之前,perl 脚本似乎没有足够的时间设置套接字。