Strange behaviour of a Socket attribute in a Moose Object
I have a Moose Object which has a IO::Socket::INET object as one of its attributes:
has socket => (
is => 'ro',
required => 1,
lazy => 1,
isa => 'IO::Socket::INET',
builder => 'connect',
);
The socket is initialized 开发者_JAVA技巧in a script that looks like this (the authentication part is removed):
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;
}
However I find strange behaviour when I run the following test code:
my $x = MyObject->new;
print $x->socket pack('I', 392);
The bytes received by the Server (A.B.C.D) are completely different from the ones I sent. I have checked that endian-ness or byte order is not an issue. In fact a simple script that creates a socket and writes the same data without using Moose works perfectly - the data is received at the server exactly as expected.
Do I have to do something more than what I am doing if my Moose attribute is a persistent IO::Socket::INET object. Is the socket attribute being closed or otherwise manipulated behind my back?
Thank you.
The print
documentation says that you should enclose anything more complicated than a scalar variable for the FILEHANDLE in a block. Have you tried:
print { $x->socket } pack ('I', 392);
Or:
$x->socket->print (pack ('I', 392));
I get a syntax error if I don't put braces around $x->socket
.
The following code works for me. Are you sure something isn't going wrong in the authentication section? Maybe look at the socket data with 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);
I cannot reproduce your problem.
I used
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);
And I got
$ nc -l -p 12345 | od -t x1
0000000 88 01 00 00
0000004
What do you get? What did print
return?
精彩评论