我有一个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对象,我是否必须做一些比我正在做的更多的事情。套接字属性是否在我背后被关闭或以其他方式操纵?
谢谢。
答案 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
返回了什么?