开发者

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?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜