Perl localhost的AnyEvent tcp服务器客户端示例在不使用TLS时挂起
在Windows上调试失败的测试时,我根据测试创建了以下脚本: TLS的输出(在取消注释以Perl localhost的AnyEvent tcp服务器客户端示例在不使用TLS时挂起,perl,anyevent,Perl,Anyevent,在Windows上调试失败的测试时,我根据测试创建了以下脚本: TLS的输出(在取消注释以TLS和TLS\u ctx开头的4行后)为: server\u监听 睡觉。。 正在等待客户端完成。。 客户端连接 服务器\u接受 客户排水管 正在等待服务器完成。。 服务器得到线路 服务器 请注意,在不使用TLS时,不会调用\u connect上的(客户端\u connect在输出中缺失) 即使客户端在不使用TLS时未连接,服务器也会接收数据并打印server-got-line。。。很奇怪 你知道不使
TLS
和TLS\u ctx
开头的4行后)为:
server\u监听
睡觉。。
正在等待客户端完成。。
客户端连接
服务器\u接受
客户排水管
正在等待服务器完成。。
服务器得到线路
服务器
- 请注意,在不使用TLS时,不会调用\u connect上的
(
在输出中缺失)客户端\u connect
- 即使客户端在不使用TLS时未连接,服务器也会接收数据并打印
。。。很奇怪server-got-line
你知道不使用TLS时有什么问题吗?从外观上看,你不是在从套接字/句柄读取数据。如果不从插座读取数据,就无法检测EOF状况 TLS行为不同的原因是TLS不模拟套接字语义,并且AnyEvent::Handle必须始终读取,即使没有显式读取请求,因此它将立即检测EOF条件 您可以通过添加on_read处理程序来检查这一点,例如,在服务器中的push_read之后或之前:
$hd->push_read (sub { });
在这种情况下,无论是否使用TLS,其行为都应大致相同。根据:
请注意,与读取队列中的请求不同,一个on_read
回调
这并不意味着您需要一些数据:如果存在EOF,并且
未完成的读取请求将标记错误。带着
on_read
回调,将调用on_eof
回调
这提示我需要一个on_read
回调,以便调用on_eof
回调。我试图将服务器更改为:
my $server = tcp_server(
$host,
undef, # service: must be either a service name or a numeric port number
# (or 0 or undef, in which case an ephemeral port will be used).
#
sub { # This is the accept callback..
my ($fh, $host, $port) = @_;
say "server_accept";
my $hd; $hd = AnyEvent::Handle->new(
fh => $fh,
timeout => 5,
on_error => sub {
say "server_error <$_[2]>";
$server_done->send; undef $hd;
},
on_eof => sub {
say "server_eof";
$server_done->send; undef $hd;
}
);
$hd->on_read(sub{ say "server on_read() callback"});
$hd->push_read (
line => sub {
say "server got line <$_[1]>";
}
);
}, # end of accept callback..
sub { # This is the prepare callback
say "server_listen";
$server_port->send ($_[2]);
}
);
my$server=tcp\u服务器(
$host,
未定义,#服务:必须是服务名称或数字端口号
#(或0或undef,在这种情况下,将使用临时端口)。
#
这是接受回调。。
我的($fh,$host,$port)=@;
说“服务器接受”;
my$hd;$hd=AnyEvent::Handle->new(
fh=>$fh,
超时=>5,
on_error=>sub{
说“服务器错误”;
$server_done->send;未定义$hd;
},
on_eof=>sub{
说“server_eof”;
$server_done->send;未定义$hd;
}
);
$hd->on_read(sub{say“server on_read()callback”});
$hd->push_-read(
行=>sub{
说“服务器上线”;
}
);
},#接受回调结束。。
sub{#这是prepare回调
说“服务器听”;
$server\u port->send($\u[2]);
}
);
现在输出为:
server_listen
Sleeping..
Waiting for client done..
client_drain
server_accept
Waiting for server done..
server got line <1>
server_eof
server\u监听
睡觉。。
正在等待客户端完成。。
客户排水管
服务器\u接受
正在等待服务器完成。。
服务器得到线路
服务器
所以它起作用了!(我仍然想知道为什么连接上的客户端未运行,即“客户端连接”未显示)。还请注意,由于没有输出行“server on_read()callback”,因此未运行on_read
回调
另请参见谢谢您的回答!奇怪的是,只有当我替换你的
$hd->push_read(sub{})时,它才起作用代码>带有$hd->on_read(sub{})代码>
$hd->push_read (sub { });
my $server = tcp_server(
$host,
undef, # service: must be either a service name or a numeric port number
# (or 0 or undef, in which case an ephemeral port will be used).
#
sub { # This is the accept callback..
my ($fh, $host, $port) = @_;
say "server_accept";
my $hd; $hd = AnyEvent::Handle->new(
fh => $fh,
timeout => 5,
on_error => sub {
say "server_error <$_[2]>";
$server_done->send; undef $hd;
},
on_eof => sub {
say "server_eof";
$server_done->send; undef $hd;
}
);
$hd->on_read(sub{ say "server on_read() callback"});
$hd->push_read (
line => sub {
say "server got line <$_[1]>";
}
);
}, # end of accept callback..
sub { # This is the prepare callback
say "server_listen";
$server_port->send ($_[2]);
}
);
server_listen
Sleeping..
Waiting for client done..
client_drain
server_accept
Waiting for server done..
server got line <1>
server_eof