2012-10-31 47 views
1

我試圖在運行應用程序的同一臺PC上模擬TCP服務器。 我不知道它是否可以在Perl中完成,因爲我不是很有經驗。TCP服務器多次接收和響應

隨着代碼下面的第一個答覆工作,但我不知道如何實現第二個。

#!/usr/bin/perl -w 

use IO::Socket::INET; 
use strict; 


my $socket = IO::Socket::INET->new('LocalPort' => '3000', 
        'Proto' => 'tcp', 
        'Listen' => SOMAXCONN) 
    or die "Can't create socket ($!)\n"; 
print "Server listening\n"; 
while (my $client = $socket->accept) { 
    my $name = gethostbyaddr($client->peeraddr, AF_INET); 
    my $port = $client->peerport; 
    while (<$client>) { 
    print "$_"; 
    print $client "RESPONSE1"; 
    } 
    close $client 
    or die "Can't close ($!)\n"; 
} 
die "Can't accept socket ($!)\n"; 

編輯:謝謝你們的輸入,我結束了與PHP完成它和它的工作,耶!

+0

你必須'fork'。看到這個問題,例如http://stackoverflow.com/questions/7662711/perl-forked-socket-server-stops-accepting-connections-when-a-client-disconnects –

+0

「fork」或使用事件驅動的io,例如, [使用Event模塊在Perl中進行事件驅動編程](http://cpansearch.perl.org/src/JPRIT/Event-1.20/Tutorial.pdf) – ErikR

+0

即使Event的作者不再推薦它,嘗試AnyEvent,POE, IO :: Async或類似的API來試試EV – MkV

回答

2

使用Net::Server進行連接,並在子變量中保持當前狀態(在此代碼中爲$ state);像這樣:

package MyServer; 
use base qw/Net::Server/; 
use strict; 
use warnings; 

sub process_request { 
    my $self = shift; 
    my $state = 0; 
    while (<STDIN>) { 
    s/\r?\n$//; # like chomp but for crlf too 
    if ($state == 0 and $_ eq 'data1') { 
     print "> okay1\n"; 
     $state++; 
    } elsif ($state == 1 and $_ eq 'data2') { 
     print "> okay2\n"; 
     $state++; 
    } else { 
     last if $state == 2; 
     $state = 0; 
    } 
    } 
} 

my $port = shift || 3000; 
MyServer->run(port => $port); 

Net :: Server POD中的示例建議使用警報超時連接,這可能適合在這裏。上面的代碼執行以下操作:

$ nc localhost 3000 
data1 
> okay1 
data2 
> okay2 
data3 
$ 

如果你需要移動到一個分叉/ preforking /非阻塞/協程驅動系統,有一個爲一個網::服務器的個性。

+0

非常感謝您的回答,我可以在if狀態data1&data2 hex中設置像這樣的 eq'\ x {de} \ x {c0} \ x {ad}',服務器似乎不當它與數據匹配時回覆 – Mark

+0

是的,unles以某種換行符終止,這將不起作用,而()讀取行時,您會想要執行類似while操作(read(* STDIN,local $ _ ,3))而不是while() – MkV

+0

如果您確實在爲字符串使用單引號,則應該使用雙引號,以便十六進制轉義工作,即$ _ eq「\ x {de} \ x {co} \ x {ad}「 – MkV

0

「蓄勢待發」的代碼:

package MyServer; 
use base qw/Net::Server/; 
use strict; 
use warnings; 

sub process_request { 
    my $self = shift; 
    my $state = 0; 
    $| = 1; 
    binmode *STDIN; 
    while (read(*STDIN, local $_, 3)) { 
    if ($state == 0 and $_ eq "\x{de}\x{c0}\x{ad}") { 
     print "\x{c4}\x{1a}\x{20}\x{de}"; 
     $state++; 
    } elsif ($state == 1 and $_ eq "\x{18}\x{c0}\x{0a}") { 
     print "\x{11}\x{01}\x{73}\x{93}"; 
     $state++; 
     last; 
    } 
    } 
} 

my $port = shift || 3000; 
MyServer->run(port => $port); 
0

在我看來,process_request子當低端口設置無法正常工作(在我的情況,端口23)。特別是只有在端口較低時,在解析數據輸入時,第一個請求包含額外的字符(但後續請求都可以)。 你有提示嗎?謝謝

相關問題