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

发布于 2024-11-01 19:49:54 字数 1037 浏览 5 评论 0原文

我有一个 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 对象,我是否需要做比我正在做的更多的事情。套接字属性是否被关闭或在我背后被操纵?

谢谢。

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 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

提笔落墨 2024-11-08 19:49:54

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);

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);
我偏爱纯白色 2024-11-08 19:49:54

我无法重现你的问题。

我使用了

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 返回了什么?

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?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文