2015-03-25 60 views
1

我正在嘗試通過管道與分叉進程進行通信。我用pipe子例程爲管道創建了filehanders,爲父進程創建了子進程的封閉閱讀器和編寫器。 但我仍然無法從管道獲得任何信息。使用管道與子進程進行通信

我的錯在哪裏?

#!/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; 
    } 

} 
} 
+2

您有一個管道,一個套接字和一個共享緩衝區。你真的需要所有這些嗎?!你的主進程阻塞'my $ connection = $ server-> accept',所以它永遠不會到達'fork',並且子進程永遠不會被創建。我建議你先讓套接字工作,然後再添加另一個IPC。 – Borodin 2015-03-25 03:05:46

回答

4

嘗試創建一個管道之後添加以下行:

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

希望這會幫助你。默認情況下,autoflush被關閉,所以也許你的問題在這裏。

+0

太棒了!有用 !!謝謝 !! – brqgddez 2015-03-25 06:01:54

相關問題