2014-06-23 76 views
2

这是我的简单服务器。当我运行它并telnet到它(端口5222),并让telnet退出它的连接时,为什么我的on_eof函数没有被调用?即为什么不是字符串“突变体!!!”印?为什么不在这个AnyEvent :: Handle示例中调用on_eof?

#!/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; 
+0

AnyEvent :: Intro上的http_get示例使用'on_eof'来捕获关闭连接。为什么我不应该这样做? – alexk

+0

行为是固定的,当我添加一个空的on_read处理程序,就像这样:'$ hdl-> on_read(sub {say“READ !!!”})''。任何人都明白为什么? – alexk

回答

1

tl; dr:没有尝试从套接字读取,EOF不能被检测到。使用 - > on_eof或 - > push_read。

龙版本:

的例子并不试图读取从手柄什么,这就是为什么AnyEvent ::句柄不尝试读取数据。在不尝试读取数据的情况下,它无法检测到EOF(POSIX API的后果)。

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

注意AnyEvent ::句柄将自动为您“start_read”当你改变“on_read”回调或推/如果未设置“on_read”并且队列中没有任何读取请求,则不会移动读取 回调,并且它会自动为您“停止读取”。

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

不请求数据时不读取数据是一种自动避免由于程序没有“足够快”地处理数据而导致的错误错误的方法:AnyEvent :: Handle根本不会从套接字读取任何内容,直到程序就如何处理数据做出决定。

在你非常不典型的例子中,你不会对套接字做任何事情。为了检测到on_eof,你可以调用 - > start_read,但这在实际的程序中不太可能有用。

+0

因为在连接发生后你可能想要推送(或不推送)一些内容,所以如果你还没有声明你的读取处理程序,AnyEvent不能分辨突发的EOF事件是否过早(on_error)或不(on_eof) – alexk

相关问题