Moose对象中Socket属性的奇怪行为

时间:2011-04-18 19:59:46

标签: perl sockets moose

我有一个Moose对象,它有一个IO :: Socket :: INET对象作为其属性之一:

has socket => (
    is => 'ro',
    required => 1,
    lazy => 1,
    isa => 'IO::Socket::INET',
    builder => 'connect',
);

套接字在一个看起来像这样的脚本中被初始化(认证部分被删除):

sub connect {
    my $self = shift;
    my $host = 'A.B.C.D';
    my $port = N;

    my $handle = IO::Socket::INET->new(
        Proto     => "tcp",
        PeerAddr  => $host,
        PeerPort  => $port
    ) or die "can't connect to port $port on $host: $!";

    $handle->autoflush(1);

   # Connect to Server with $handle and authenticate
   # and if successful .......
    return $handle;
}

但是,当我运行以下测试代码时,我发现了奇怪的行为:

my $x = MyObject->new;
print $x->socket pack('I', 392);

服务器(A.B.C.D)收到的字节与我发送的字节完全不同。我已经检查过endian-ness或字节顺序不是问题。 实际上,创建套接字并在不使用Moose的情况下写入相同数据的简单脚本可以完美地工作 - 数据在服务器上完全按预期接收

如果我的Moose属性是持久的IO :: Socket :: INET对象,我是否必须做一些比我正在做的更多的事情。套接字属性是否在我背后被关闭或以其他方式操纵?

谢谢。

2 个答案:

答案 0 :(得分:4)

print文档说明你应该为块中的FILEHANDLE包含比标量变量更复杂的东西。你试过了吗?

print { $x->socket } pack ('I', 392);

或者:

$x->socket->print (pack ('I', 392));

如果我没有在$x->socket附近添加大括号,我会收到语法错误。

以下代码适用于我。您确定身份验证部分没有出错吗?也许用wireshark查看套接字数据?

package Test;
use Moose;
use IO::Socket::INET;

has socket => (
    is => 'ro',
    required => 1,
    lazy => 1,
    isa => 'IO::Socket::INET',
    builder => 'connect',
);

sub connect {
        my $sock = IO::Socket::INET->new (
                Proto => "tcp",
                PeerAddr => "127.0.0.1",
                PeerPort => 2000,
        ) or die;
        $sock;
}

package main;

my $x = Test->new;
print { $x->socket } pack ('I', 392);

答案 1 :(得分:3)

我无法重现你的问题。

我用过

use strict;
use warnings;

use IO::Socket::INET;
use Moose;

has socket => (
    is => 'ro',
    required => 1,
    lazy => 1,
    isa => 'IO::Socket::INET',
    builder => 'connect',
);

sub connect {
    my $self = shift;
    my $host = 'localhost';
    my $port = 12345;

    my $handle = IO::Socket::INET->new(
        Proto     => "tcp",
        PeerAddr  => $host,
        PeerPort  => $port
    ) or die "can't connect to port $port on $host: $!";

   # Connect to Server with $handle and authenticate
   # and if successful .......
    return $handle;
}

my $x = __PACKAGE__->new;
print { $x->socket } pack('I', 392);

我得到了

$ nc -l -p 12345 | od -t x1
0000000 88 01 00 00
0000004

你得到了什么? print返回了什么?