为什么在这个AnyEvent :: Handle示例中没有调用on_eof?

时间:2014-06-23 19:28:45

标签: perl anyevent

这是我的简单服务器。当我运行它并telnet到它(端口5222),并让telnet退出它的连接时,为什么我的on_eof函数没有被调用?即为什么不是字符串" CATASTROPHE !!!"印刷?

#!/usr/bin/perl

use v5.18;
use warnings;

use EV;
use AnyEvent;
use AnyEvent::Socket;
use AnyEvent::Handle;

our $hdl;

my $server = tcp_server undef, 5222, sub {
    my ($fh) = @_;

    $hdl = AnyEvent::Handle->new(fh => $fh);
    $hdl->on_eof(sub {
        my ($handle) = @_;

        say "CATASTROPHE!!!";
    });
};

EV::run;

1 个答案:

答案 0 :(得分:1)

tl; dr:无需尝试从套接字读取,无法检测到EOF。使用 - > on_eof或 - > push_read。

长版:

该示例不会尝试从句柄中读取任何内容,这就是为什么AnyEvent :: Handle不会尝试读取数据的原因。在不尝试读取数据的情况下,它无法检测到EOF(POSIX API的结果)。

此行为仅在start_read / stop_read方法的描述中间接描述:

  

注意AnyEvent :: Handle将自动" start_read"当你改变" on_read"回调或推/取阅读   回调,它   将自动" stop_read"当你没有" on_read"已设置,队列中也没有任何读取请求。

它的行为原因是,在基于事件的程序中,在读取数据(内部完成)和排队读取回调之间可能有任何时间。由于接收不期望的数据是错误的(并且由于没有使错误可能使读缓冲区溢出,导致错误),因此需要某种方法来避免这些错误。

当没有请求数据时,不读取数据是一种自动方法,可以避免因程序不够快而导致的虚假错误"处理数据:AnyEvent :: Handle根本不会从套接字中读取任何内容,直到程序决定如何处理数据。

在你不太典型的例子中,你不能对套接字做任何事情。要检测到on_eof,您可以调用 - > start_read,但这在现实世界的程序中不太可能有用。