Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl中的非致命性处理错误_Perl_Encryption_Error Handling_Cryptography - Fatal编程技术网

Perl中的非致命性处理错误

Perl中的非致命性处理错误,perl,encryption,error-handling,cryptography,Perl,Encryption,Error Handling,Cryptography,在上一篇文章中,建议我使用该模块导出和发送RSA密钥。但是,我发现该模块似乎无法非致命地处理错误,因此,只要发送一个格式错误的字符串(即不是RSA密钥),服务器程序就会在尝试使用它创建新对象时崩溃,并显示以下消息: server.pl第46行的密钥格式无法识别 第46行包含代码 $clients{$cur_client}->{pub_key} = Crypt::OpenSSL::RSA->new_public_key($message) or do {

在上一篇文章中,建议我使用该模块导出和发送RSA密钥。但是,我发现该模块似乎无法非致命地处理错误,因此,只要发送一个格式错误的字符串(即不是RSA密钥),服务器程序就会在尝试使用它创建新对象时崩溃,并显示以下消息:

server.pl第46行的密钥格式无法识别

第46行包含代码

$clients{$cur_client}->{pub_key}    = Crypt::OpenSSL::RSA->new_public_key($message) or do {
            server_log "Bad key exchange, dropping user $address:$port..."; 
            delete $clients{$cur_client};
            next;
        }; # Key exchange
我该如何解决这个问题


编辑:

您需要使用的块形式来防止程序在引发异常时死机。不幸的是,
eval
的简单使用充满了尴尬的角落案例,最好使用为您处理这些案例的模块

为了达到问题中代码的目的,您可以编写如下内容。显然,您必须为变量提供有用的数据

重要的是要注意
try
catch
是子例程。这意味着您在
catch
之后需要一个分号,并且您不能在
catch
中使用
next
,因为您不能在子例程中使用分号。您必须保留某种状态集,以便后续代码可以在那里执行任何必要的操作,在这种情况下,我只需检查
$clients{$cur_client}
是否仍然存在,如果出现问题,它将被
catch
例程删除

还需要说明的是,
catch
例程中的
$\ucode>中提供了
die
字符串,因此您可以检查失败的原因。在这种情况下,
catch
只希望处理
无法识别的密钥格式
错误,因此代码检查这确实是失败的原因。如果没有,则它会发出另一个
die$\uu
,以反映发生了未处理的错误

use strict;
use warnings 'all';

use Crypt::OpenSSL::RSA;
use Try::Tiny;

my %clients = ( aa => {} );
my $message = 'xxx';
my ($address, $port) = qw/ 127.0.0.1 80 /;

for my $cur_client ( keys %clients ) {

    try {
        $clients{$cur_client}{pub_key} = Crypt::OpenSSL::RSA->new_public_key($message);
    }
    catch {
        if ( /unrecognized key format/ ) {
            server_log("Bad key exchange, dropping user $address:$port...");
            delete $clients{$cur_client};
        }
        else {
            die $!;
        }
    };

    next unless exists $clients{$cur_client};

    # More handling of $cur_client in the case that
    # the call to new_public_key succeeds
}

sub server_log {
    print "Logging: $_[0]\n";
}

您需要使用的块形式来防止程序在引发异常时死机。不幸的是,
eval
的简单使用充满了尴尬的角落案例,最好使用为您处理这些案例的模块

为了达到问题中代码的目的,您可以编写如下内容。显然,您必须为变量提供有用的数据

重要的是要注意
try
catch
是子例程。这意味着您在
catch
之后需要一个分号,并且您不能在
catch
中使用
next
,因为您不能在子例程中使用分号。您必须保留某种状态集,以便后续代码可以在那里执行任何必要的操作,在这种情况下,我只需检查
$clients{$cur_client}
是否仍然存在,如果出现问题,它将被
catch
例程删除

还需要说明的是,
catch
例程中的
$\ucode>中提供了
die
字符串,因此您可以检查失败的原因。在这种情况下,
catch
只希望处理
无法识别的密钥格式
错误,因此代码检查这确实是失败的原因。如果没有,则它会发出另一个
die$\uu
,以反映发生了未处理的错误

use strict;
use warnings 'all';

use Crypt::OpenSSL::RSA;
use Try::Tiny;

my %clients = ( aa => {} );
my $message = 'xxx';
my ($address, $port) = qw/ 127.0.0.1 80 /;

for my $cur_client ( keys %clients ) {

    try {
        $clients{$cur_client}{pub_key} = Crypt::OpenSSL::RSA->new_public_key($message);
    }
    catch {
        if ( /unrecognized key format/ ) {
            server_log("Bad key exchange, dropping user $address:$port...");
            delete $clients{$cur_client};
        }
        else {
            die $!;
        }
    };

    next unless exists $clients{$cur_client};

    # More handling of $cur_client in the case that
    # the call to new_public_key succeeds
}

sub server_log {
    print "Logging: $_[0]\n";
}

我知道这个问题已经得到了回答,但我想我应该添加它,这样人们就知道,在Perl中捕获错误不需要模块,它已经内置了。下面是一些演示Perls内置异常处理的代码

#!/usr/bin/perl
use strict;
use warnings;
my $a = 100;
my $res = 0;  
eval {
  $res = $a/0;
};
if($@) {
  print("I just caught a divide by zero here... $@\n");
}
这是另一个例子

eval {
  die "please die\n";;
}; 
if($@) {
  print("No, you cannot die just yet... $@\n");
}

我已经使用这个习惯用法很多年了,它的效果非常好。

我知道这个问题已经得到了回答,但我想我应该添加它,这样人们就知道,在Perl中捕获错误不需要模块,它已经内置了。下面是一些演示Perls内置异常处理的代码

#!/usr/bin/perl
use strict;
use warnings;
my $a = 100;
my $res = 0;  
eval {
  $res = $a/0;
};
if($@) {
  print("I just caught a divide by zero here... $@\n");
}
这是另一个例子

eval {
  die "please die\n";;
}; 
if($@) {
  print("No, you cannot die just yet... $@\n");
}

我已经使用这个成语很多年了,它很有魅力。

公认的答案首先提到了
eval
,然后建议
Try::Tiny
更可取,因为
eval
有很多陷阱,你可能会落入其中,
Try::Tiny
可以避免它们。例如,如果
$@
具有非真值,则错误处理代码将无法检测到发生错误。公认的答案首先提到了
eval
,然后建议首选
Try::Tiny
,因为
eval
有许多陷阱,您可能会落入其中,而
Try::Tiny
可以避免这些陷阱。例如,如果
$@
具有非真值,则错误处理代码将无法检测到发生错误。