加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

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字节长度的串
}


服务器端使用select复用模式

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来进行改造

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读