Странное поведение атрибута Socket в объекте Moose - PullRequest
1 голос
/ 18 апреля 2011

У меня есть объект 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);

Полученные сервером (ABCD) байты полностью отличаются от тех, которые япослал.Я проверил, что порядок байтов или байтов не является проблемой. На самом деле простой скрипт, который создает сокет и записывает те же данные без использования Moose, работает отлично - данные принимаются на сервере точно так, как ожидалось .

Должен ли я делать что-то большее, чем то, что я делаю, если мой атрибут Moose является постоянным объектом IO :: Socket :: INET.Атрибут сокета закрывается или иным образом манипулируется за моей спиной?

Спасибо.

Ответы [ 2 ]

4 голосов
/ 19 апреля 2011

Документация 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);
3 голосов
/ 19 апреля 2011

Я не могу воспроизвести вашу проблему.

Я использовал

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 вернуло?

...