perl coro socket编程(1)
发布时间:2020-12-16 00:20:12 所属栏目:大数据 来源:网络整理
导读:coro提供了perl的非阻塞io.但是作者提供的文档太简略了,例子也没有. 自己尝试写了几个例子. 分别实现CU上仙子提供的例子以及AE自带的echo server例子 相关的模块有 coro:;socket,coro::handle ae::socket,ae::handle ? 先看看传统的socket编程(CU上仙子提供
coro提供了perl的非阻塞io.但是作者提供的文档太简略了,例子也没有. 自己尝试写了几个例子. 分别实现CU上仙子提供的例子以及AE自带的echo server例子 相关的模块有 coro:;socket,coro::handle ae::socket,ae::handle ? 先看看传统的socket编程(CU上仙子提供的例子) 客户端使用多进程并发 use strict; use IO::Socket; my @childs; for (1..3) { # fork 3个子进程,同时发送数据 my $child = fork; if ($child) { push(@childs,$child); } else { # 创建到server的连接socket my $sock=IO::Socket::INET->new(PeerAddr => 'localhost',PeerPort => 1234,Proto => 'tcp') or die $@; for (1..10) { # 每个子进程里,发送10次数据 print $sock random() . "n"; select(undef,undef,0.25); # 每发送一次,就休眠0.25秒 } $sock->close or die $!; # 发送完后关闭socket,并退出子进程 exit 0; } } for (@childs) { # 回收子进程 my $tmp = waitpid($_,0); print "done with pid $tmpn"; } sub random { # 该函数产生随机字串 my @x=(0..9,'a'..'z','A'..'Z'); join '',map {$x[int rand @x]} 1..49; # 返回49字节长度的串 }
use strict; use IO::Socket; use IO::Select; $|++; # 因为print到终端,所以这里要打开autoflush my $s = IO::Socket::INET->new(LocalAddr => 'localhost',# 创建一个侦听socket LocalPort => 1234,Listen => 5,Proto => 'tcp') or die $@; my $read_set = new IO::Select(); # 创建一个IO::Select目标 $read_set->add($s); # 把上述侦听socket加入IO::Select的检查队列 while (1) { # 一个死循环 # IO::Select有一个静态select方法,第一个参数如果设置,表示检查可读的socket # 该方法一直block,直到有可用的句柄返回 # 返回一个三参数列表,第一个参数表示可读的socket句柄集合(一个数组引用) my ($rh_set) = IO::Select->select($read_set,undef); foreach my $rh (@$rh_set) { # 遍历可读的socket # 如果当前可读的socket等于侦听socket,那么说明有请求进来,应该及时accept # accept后,把已建立连接的socket句柄加入检查队列 if ($rh == $s) { my $ns = $rh->accept(); $read_set->add($ns); # 使用sysread读取数据,每次读取32字节,并且只处理这32字节 # 如果客户端发送多于32字节的数据包,会分几次处理,如果几个客户端同时发送,处理过程是无序的 # 避免使用<>方式读取socket,因为<>面向行读取,perlio对它做了缓冲,IO::Select看不到这个缓冲 }else { my $buf = undef; if (sysread($rh,$buf,32)) { print $rh->fileno," "," "; # sysread的返回是读取的字节数量,如果返回0,则说明抵达文件末尾(EOF) # 如果sysread返回0,那么说明客户端关闭socket,我们从检查队列里删除该句柄,同时关闭socket句柄 } else { print "no more data,close socket " . $rh->fileno . "n"; $read_set->remove($rh); $rh->close; } } } } 下面使用coro来进行改造 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |