使用管道与子进程通信

时间:2015-03-25 01:40:15

标签: linux perl sockets pipe fork

我正在尝试通过管道与分叉进程通信。我已经为管道子程序创建了文件管理器,为子进程创建了封闭式读取器,为父进程创建了编写器。 但我仍然无法从管道获取任何信息。

我的错在哪里?

#!/usr/bin/perl
# ioforkserv.pl
use warnings;
use strict;
use IO::Socket;
use IPC::Shareable;

my $buffer;
my $handle = tie $buffer, 'IPC::Shareable', undef, { destroy => 1 };
$buffer = "Buffer init";
# Turn on autoflushing
$|=1;
# Open pipe
my ($reader, $writer);
pipe($reader,$writer);

my $port = 4444;
my $server = IO::Socket->new(
    Domain => PF_INET,
    Proto => 'tcp',
    LocalPort => $port,
    Listen => SOMAXCONN,
    Reuse => 1,
);
die "Bind failed: $!n" unless $server;
# tell OS to clean up dead children
$SIG{CHLD} = 'IGNORE';
print "Multiplex server running on port $port...\n";
print "Initial buffer value is ".$buffer."\n";

while (my $connection = $server->accept) {
    my $name = $connection->peerhost;
    my $port = $connection->peerport;
    if (my $pid = fork) {
        close $connection;
        print "Forked child $pid for new client $name:$port\n";
        next; # on to the next connection
        } else {
        # child process - handle connection
        close($reader);
        $buffer = "Child # $$\n";
        print $connection "You're connected to the server!\n";
        while (<$connection>) {
            print $writer "Client $name:$port says: $_";
            print $connection "Message received OK\n";
            print "Buffer = $buffer\n";
        }
        print "Client $name:$port disconnected\n";
        $connection->shutdown(SHUT_RDWR);
        exit;
    }
    close($writer);
    while (my $data = <$reader>) {
       print "In pipe : ".$data."\n";
    }
}

修改 我已经编辑了代码,但它只在连接打印后显示管道中的数据,它有什么问题?

#!/usr/bin/perl
# ioforkserv.pl
use warnings;
use strict;
use IO::Socket;
use IPC::Shareable;
my $buffer ;
my $handle = tie $buffer, 'IPC::Shareable', undef, { destroy => 1 };
$buffer = "Buffer init";
# Turn on autoflushing
$|=1;
# Open pipe
my ($reader, $writer);
pipe($reader,$writer);

my $port = 4444;
my $server = IO::Socket->new(
    Domain => PF_INET,
    Proto => 'tcp',
    LocalPort => $port,
    Listen => SOMAXCONN,
    Reuse => 1,
);
die "Bind failed: $!n" unless $server;
# tell OS to clean up dead children
$SIG{CHLD} = 'IGNORE';
print "Multiplex server pid $$ running on port $port...\n";
print "Initial buffer value is ".$buffer."\n";
#Creating new process for taking data from pipe 
my $chpid = fork();
if( $chpid == 0 ){
    close($writer);
    print "Before Reading from pipe $$\n";
    while (my $data = <$reader>) {
       print "In pipe  $$: ".$data."\n";
    }
    print "After reading from pipe $$ \n";
    exit 0;
} else {
print "This is parent process and child ID is $$ and ch $chpid\n";
while (my $connection = $server->accept) {
    my $name = $connection->peerhost;
    my $port = $connection->peerport;
    if (my $pid = fork) {
        close $connection;
        print "Forked child $pid for new client $name:$port\n";
        next; # on to the next connection
        } else {
        # child process - handle connection
        close($reader);
        $buffer = "Child # $$\n";
        print $connection "You're connected to the server!\n";
        while (<$connection>) {
            print $writer "Client $name:$port says: $_ \n";
            print "Client $name:$port says: $_";
            print $connection "Message received OK\n";
            print "Buffer = $buffer\n";
        }
        print "Client $name:$port disconnected\n";
        $connection->shutdown(SHUT_RDWR);
        exit;
    }

}
}

1 个答案:

答案 0 :(得分:2)

尝试在创建管道后添加以下行:

pipe($reader,$writer);
$writer->autoflush(1);  

希望这会对你有所帮助。默认情况下autoflush被关闭,所以也许你的问题就在这里。