2012-10-31 21 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)。特别是只有在端口较低时,在解析数据输入时,第一个请求包含额外的字符(但后续请求都可以)。 你有提示吗?谢谢

相关问题