在Perl中通过网络发送二进制安全数据

fri*_*edo 5 unicode perl network-programming utf-8

我正在实现一个向服务器发送消息的网络客户端.消息是字节流,协议要求我事先发送每个流的长度.

如果我给出的消息(通过使用我的模块的代码)是一个字节字符串,那么长度很容易给出length $string.但如果它是一串字符,我需要按摩它以获得原始字节.我现在正在做的基本上是这样的:

my $msg = shift;   # some message from calling code
my $bytes;
if ( utf8::is_utf8( $msg ) ) { 
    $bytes = Encode::encode( 'utf-8', $msg );
} else { 
    $bytes = $msg;
}

my $length = length $bytes;
Run Code Online (Sandbox Code Playgroud)

这是处理这个问题的正确方法吗?它似乎工作到目前为止,但我还没有做过任何严肃的测试.这种方法有哪些潜在的缺陷?

谢谢

Ilm*_*nen 4

您不应该真正猜测您的输入是什么。 定义您的代码以接受字节字符串或 Unicode 字符串,并将其留给调用者将输入转换为正确的格式(或为调用者提供某种方式来指定他们提供的字符串类型)。

如果您将代码定义为接受字节字符串,则以上任何字符\xFF都是错误的。

如果您将代码定义为接受 Unicode 字符串,那么您可以将它们转换为字节Encode::encode_utf8()(并且无论 Perl 内部如何表示它们都应该这样做)。

无论如何,调用utf8::is_utf8()通常是一个错误 - 您的程序不应该关心字符串的内部表示,而只关心它们包含的实际数据(字符序列)。其中一些字符(特别是在\x80to范围内的字符\xFF)是否在内部由一个或两个字节表示并不重要。

诗。阅读perldoc Encode可能有助于澄清 Perl 中字节和字符的问题。