【问题标题】:Using Event::Lib to make a perl chat client使用 Event::Lib 制作 perl 聊天客户端
【发布时间】:2013-11-19 18:37:49
【问题描述】:

我正在尝试学习 perl 以及事件驱动编程。我制作了一个客户端,它附加到特定的 IP 和端口号,并通过套接字侦听消息。

my $socket = new IO::Socket::INET (
PeerHost => $server,
PeerPort => '5000',
Proto => 'tcp',
);

然后我监听服务器消息,并且我想从 STDIN 读取。为此,我尝试使用 CPAN 中的库 Event::Lib 实现事件编程

sub do_client{
my ($ev,$type) = @_;
my $event = shift;
my $fh = $event->fh;
$cl_data = <$fh>;
chomp $cl_data;
print $socket "$cl_data\r\n";
$event->add; 
}

sub do_server{
my ($ev,$type) = @_;
my $event = shift;
my $fh = $event->fh;
$sv_data = <$fh>;
chomp $sv_data;
print "$sv_data\n";
$event->add;
}


event_new($socket, EV_WRITE, \&do_server)->add;
event_new(STDIN, EV_WRITE, \&do_client)->add;
event_mainloop;

现在问题来了。在从套接字读取的每一行之后,我认为处理程序会转到 STDIN 事件并等待我的返回。如果我不从键盘按返回,则处理程序永远不会从套接字读取并打印它。 (它没有同步客户端和服务器通信)

这是我获得输出的方式。

Connection established
[Server]
    **** waits here for me to enter return *** 
Whats your name?

我正在尝试制作一个聊天客户端。因此,每当我向终端写入信息时,它都应该转到 STDIN 事件,并在套接字中有消息时打印出消息。 请告诉我在这里做错了什么。

【问题讨论】:

  • 查看 Event::Lib 页面,STDIN 调用应该是 event_new(*STDIN, EV_READ, \&handler)->add(1.5);根据我的回答,我仍然会选择 AnyEvent
  • 我建议完全不要使用 Event::Lib - 底层 C 库很好,但是模块非常损坏并且不再维护(不可避免地会导致随机内存损坏)。一些更好的选择是 Event、Glib、EV 等等。

标签: perl sockets event-handling client


【解决方案1】:

您可能希望在代码中使用更高级别的模块。当您执行&lt;STDIN&gt; 时,它会阻塞

AnyEvent 通过事件驱动编程提供非阻塞 IO

   my $w; $w = AnyEvent->io (fh => \*STDIN, poll => 'r', cb => sub {
      chomp (my $input = <STDIN>);
      warn "read: $input\n";
      undef $w;
   });

这将在 STDIN 上不阻塞,然后用

清除观察者
undef $w;

【讨论】:

  • 嗯,您使用&lt;&gt; 使其阻塞,它会一直读取直到遇到换行符。你不应该在那里使用&lt;&gt;。您应该只阅读可用的内容,将其添加到缓冲区中,然后检查缓冲区中是否有换行符。
  • AnyEvent::IO 通过仅在安全读取一行时触发事件来处理这一点。如果 OP 正在等待某个按键 search.cpan.org/~pevans/AnyEvent-TermKey-0.02/lib/AnyEvent/… 但我没有使用这个
  • 不,当有 data 要读取时,它会触发事件。 (“cb 是每次文件句柄准备就绪时调用的回调。”)可能没有
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-12
  • 2011-01-04
  • 1970-01-01
  • 2018-05-24
  • 1970-01-01
  • 2020-12-19
相关资源
最近更新 更多