perl,使用 IO::Select 和 IO::Socket::INET 读取阻塞

编程入门 行业动态 更新时间:2024-10-10 16:18:35
本文介绍了perl,使用 IO::Select 和 IO::Socket::INET 读取阻塞的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

这个服务器工作正常,但如果我这样做

This server works fine but if I do this

bash$ (echo -n "abcd" ;sleep 50 ; echo "efgh") |nc 本地主机 9090

bash$ (echo -n "abcd" ;sleep 50 ; echo "efgh") | nc localhost 9090

服务器阻塞了 50 秒.在我的完整代码中,我有多个 IO::Select::INET.我有另一个套接字侦听其他端口(1234),当服务器被睡眠阻塞时,我无法处理该端口中的任何内容.我尝试通过 getc 更改 getline 但我只读取了第一个字母a"并且它阻塞了.

The server blocks for 50 seconds.In my complete code I have more than one IO::Select::INET. I have another socket listen other port (1234), and I can't process anything in that port while the server is blocking by the sleep. I try change the getline by getc but I only read the first letter "a" and it blocks.

有人可以帮助我吗?

use common::sense; use IO::Select; use IO::Socket; use constant PORT1 => 9090; use constant TIMEOUT => 1; my $event_socket = new IO::Socket::INET(Listen => 1, LocalPort => PORT1, ReuseAddr => 1) or die "Can't bind event_socket: $@\n"; my $sel = IO::Select->new; $sel->add($event_socket); my $event_emiter = undef; while(1){ foreach my $sock (my @ready = $sel->can_read(TIMEOUT)) { if ($sock == $event_socket) { my $new = $event_socket->accept; binmode($new, ":encoding(UTF-8)"); $sel->add($new); $event_emiter=$new; warn "[event socket] connect from ",$new->peerhost, "\n"; } elsif ($sock == $event_emiter) { unless($sock->eof){ my $recv_data = $sock->getline; warn "[event socket] LOL '$recv_data'\n"; } else { $sel->remove($sock); $sock->close; $event_emiter = undef; warn "[socket] disconnect\n"; } } else { $sel->remove($sock); $sock->close; warn "[socket] disconnect\n"; } } }

推荐答案

不是读取可用数据,而是读取直到读取换行符.始终使用 sysread.

Rather than reading available data, you're reading until you read a newline. Always use sysread.

改变

elsif ($sock == $event_emiter) { unless($sock->eof){ my $recv_data = $sock->getline; warn "[event socket] LOL '$recv_data'\n"; } else { $sel->remove($sock); $sock->close; $event_emiter = undef; warn "[socket] disconnect\n"; } }

elsif ($sock == $event_emiter) { our $buf; local *buf = \$bufs{$fh}; # alias $buf = $bufs{$fh}; my $rv = sysread($fh, $buf, 64*1024, length($buf)); if (!$rv) { if (defined($rv)) { # EOF # ... Handle anything left in $buf ... } else { # Error # ... Handle error ... } delete $bufs{$fh}; $sel->remove($sock); $sock->close; $event_emiter = undef; warn "[socket] disconnect\n"; next; } while ($buf =~ s/^(.*)\n//) { warn "[event socket] LOL '$1'\n"; } }

并在选择循环之外添加my %bufs;.

And add my %bufs; outside the select loop.

更多推荐

perl,使用 IO::Select 和 IO::Socket::INET 读取阻塞

本文发布于:2023-11-25 17:54:28,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1630741.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:IO   perl   Select   INET   Socket

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!