perl - 使用 Event::Lib 制作 perl 聊天客户端

标签 perl sockets event-handling client

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

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

然后我收听服务器消息,并且我想从 STDIN 中读取。为此,我尝试使用库 Event::Lib 实现事件编程。来自 CPAN
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 事件,并在套接字中有消息时打印出消息。
请告诉我在这里做错了什么。

最佳答案

您可能希望在代码中使用更高级别的模块。当你做 <STDIN>然后它会阻塞

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;

关于perl - 使用 Event::Lib 制作 perl 聊天客户端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20079412/

相关文章:

javascript - 在嵌套的div jquery中按类查找id

perl - 如何在 Log4perl 中仅记录 INFO 级别?

mysql - Perl 从 xls 读取插入到 mysql

linux - Freepascal,Indy SVN 主干版本,PHP 客户端在传输 XML 时没有收到任何信息,直到删除编码转换

javascript - 事件监听器与事件处理程序

javascript - 在 JQuery 中防止多次点击

perl - 可以安全地忽略 "Attempt to free unreferenced scalar"错误吗?

database - Perl:如何避免全局并保持数据库连接

c - 获取地址 IP 并使用套接字连接到它

Java UDP 服务器只接收数组中的第一个整数