我正在用perl编写一个小型服务器。有一些小问题。当客户给我这样的句子“op:xxx:xxx:xxx”时,我会得到操作。然后根据操作是做什么的。如果op是adduser等,它将起作用。 (我使用if op eq“adduser”......) 但是当我得到一个“getList:xxx:xxx”并且我得到$ op = getList时,它不能像“if $ op eq”getList“”那样传递它。我知道,这一定是我的错。但我找不到它。 谢谢大家。
use warnings;
use strict;
package MyPackage;
use base qw(Net::Server);
our %data_base;
our %tag_base;
sub list {
my %resault;
foreach ( keys %tag_base) {
print STDERR $_ . "1";
my @tags = split /:/, $tag_base{$_};
foreach ( @tags) {
$resault{$_} ++;
}
}
my @tags;
foreach ( keys %resault) {
push @tags, "$_,$resault{$_}";
}
$_ = join ";", @tags;
print ;
print STDERR ;
}
sub users {
my $topic = shift;
my @users;
foreach ( keys %tag_base) {
push @users, $_ if $tag_base{$_} =~ /$topic/;
}
$_ = join ";", @users;
print ;
}
sub process_request {
my $self = shift;
my $person;
my @info;
while (<STDIN>) {
my @gets = split /:/, $_;
print STDERR "@gets\n";
# $data_base{shift @person} = join ":", @person;
my $op = shift @gets;
$op =~ s/\s//;
print STDERR $op . "\n";
if ( $op eq "adduser") {
my $user_name = shift @gets;
if ( exists $data_base{$user_name}) {
print "already_exist";
} else {
$data_base{$user_name} = join ":", @gets;
print "addUserSu";
}
} elsif ( $op eq "login") {
my $login_name = shift @gets;
my $login_pw = shift @gets;
if ( defined $data_base{$login_name}) {
$person = $data_base{$login_name};
@info = split /:/, $person;
$info[0] =~ s/\s+//;
if ($login_pw eq $info[0]) {
print "$person";
} else {
print "/$info[0]/";
}
} else {
print "unexist_user";
}
} elsif ( $op eq "addTag") {
my $tag_user = shift @gets;
$tag_base{$tag_user} = join ":", @gets;
print "addTagSu";
} elsif ( $op eq "getList") {
print STDERR "right";
&list;
} elsif ( $op eq "getUsers") {
&users;
}
}
}
MyPackage->run(port => 13800);
答案 0 :(得分:5)
我可以看到两个(简单)原因可能会失败:
$op =~ s/\s//;
您只删除一个空格:第一个空格。如果您打算删除所有空格,则需要s/\s+//g
。
第二名:
字符串,变量名和命令中的随机大写字母是邪恶的。 eq
区分大小写,因此如果$op
为"getlist"
,则if ($op eq "getList")
将为false。除非资本化对您很重要,否则您可以if (lc($op) eq "getlist")
。
如果没有样本输入,预期输出和实际输出,这只不过是猜测。
另外,作为调试语句,这是无用的:
print STDERR $op . "\n";
很容易混淆和忽视。例如,如果$op
为空,则只会在错误日志中生成一个空行。使用:
print STDERR "OP is: '$op'\n";
现在,您将能够识别应显示$op
的行,并且您将更容易看到它周围的空白。
答案 1 :(得分:1)
你正在阅读字符串而不是扼杀它们。
即
运行代码时:
addtag:fred:barney
输入存储为fred => "barney\n"
当你getList
时,输出为:
barney
,1;
我怀疑客户端期待1行输出:
barney,1;
所以,只需在代码中添加一个chomp:
while (<STDIN>) {
chomp;
my @gets = split /:/, $_;