coro::socket+coro::handle echo server(2)-sysread 的改造
来源:互联网 发布:淘宝图片上传软件 编辑:程序博客网 时间:2024/06/01 12:32
前面的server是用getline实现的,想改用sysread实现
但是coro默认的sysread的行为是模拟系统的sysread,和我的需求不太一样
我希望是指定读取nbyte的字符,如果不满nbyte,就全部返回,为空就等待
而sysread会等待达到指定长度直到超时
需要对sysread对应的READ方法作如下修改
sub READ { my $len = $_[2]; my $ofs = $_[3]; #偏移量,默认为0 my $res; # first deplete the read buffer if (length $_[0][3]) { my $l = length $_[0][3]; if ($l <= $len) { #收到数据不足指定长度,buf为数据,,返回值为长度 substr ($_[1], $ofs) = $_[0][3]; $_[0][3] = ""; $len -= $l; $ofs += $l; $res += $l; # return $res unless $len; #原来只有读够才返回 return $res if $l; } else { #超过指定长度,返回部分.返回值为长度,数据在buf substr ($_[1], $ofs) = substr ($_[0][3], 0, $len); substr ($_[0][3], 0, $len) = ""; return $len; } } while() { my $r = sysread $_[0][0], $_[1], $len, $ofs; if (defined $r) { $len -= $r; $ofs += $r; $res += $r; ######################增加eof的处理 if($r ==0 ){ # EOF return 0 unless length $_[0][3]; } ###################### #last unless $len && $r; #原来只有读够或者没读到,才返回, last if $r; #改为if $r,只要有返回就last } elsif ($! != EAGAIN && $! != EINTR && $! != WSAEWOULDBLOCK) { last; } last if $_[0][8] || !&readable; } $res}
为了不改动原有的sysread功能,我参照readline实现了一个新的READSTR方法,就通过原来的read接口(反正原来read和sysread是一样的)
感觉这样更好一些
#目标:实现一个类似getline的方法,读到指定长度或者buf为空就返回,不判断超时sub READSTR { my $len = $_[2]; my $ofs = $_[3]; my $res; while () { my $len = sysread $_[0][0],$_[0][3], $len, $ofs; unless ($len) { if (defined $len) { # EOF return undef unless length $_[0][3]; return delete $_[0][3]; } elsif (($! != EAGAIN && $! != EINTR && $! != WSAEWOULDBLOCK) || !&readable) { return length $_[0][3] ? delete $_[0][3] : undef; } } if (length $_[0][3]) { my $l = length $_[0][3]; if ($l <= $len) { #不足指定长度,全部返回 return delete $_[0][3]; } else{#超过指定长度,返回部分 $res = substr ($_[0][3], 0, $len); #清空部分buf substr ($_[0][3], 0, $len) = ""; return $res; } } }}
使用该方法改造的coro echo server
#!/bin/env perl#sever coro::socket+coro::handle来实现#不使用getline,改为sysread(不完美)use strict;use Coro;use AnyEvent;#这个是ae的perl实现,要比EV慢一点点use AnyEvent::Impl::Perl;use Coro::Socket;use Coro::Handle; my $port = 11212;#1.创建监听端口$|++; # 因为print到终端,所以这里要打开autoflushmy $s = Coro::Socket->new(LocalAddr => 'localhost', # 创建一个侦听socket LocalPort => $port, Listen => 5, Proto => 'tcp') or die $@; #2.处理handlemy @coro;while(1){ my ($fh, $peername) = $s->accept; next unless $peername; print "accepet new sock at" . $fh->fileno . "\n"; &doit($fh); } sub doit($){my ($fh)=@_;push @coro, async { $fh->autoflush(1); my $line=""; #while(my $line=$fh->readline()){ #while(my $ret=$fh->sysread($line,64)){ #while($fh->readable){ while(my $line=$fh->read($buf,32)){ #my $line=$fh->readline(); #my $ret=$fh->recv($line,32); #my $ret=$fh->sysread($line,32); print $fh->fileno, " ", $line, " "; $fh->print($line); } print "no more data, close socket " . $fh->fileno . "\n"; $fh->close; #关闭协程 return; } }
说明,在这个地方卡了很久.
对coro的readble,sysread这些方法理解不透.(不明白从原来的阻塞方式改为现在的非阻塞方式究竟有哪些变化)
作者只是一句Work like their function equivalents轻轻带过(囧阿,similar...)
后来还是参照源码,添加打印信息,一点点摸索.
目前还是对readable的实现不理解,感觉不像作者说的
Wait until the filehandle is readable or writable (and return true) or
until an error condition happens (and return false).
而是始终为true.
否则用readable配合recv等直读方法也是可以的
- coro::socket+coro::handle echo server(2)-sysread 的改造
- corc::socket+coro::handle server-echo server
- Anyevent::socket和Coro::Handle组合,echo server(完结)
- perl coro socket编程(2)-客户端coro改造
- coro::socket+coro::handle client编程(测试client)
- anyevent::socket+coro::handle client编程(测试客户端)
- perl coro socket编程(1)
- coro学习2-并行ping
- anyevent::socket+anyevent::handle server编程 (echo server改造 + 测试server)
- coro+io::select实现无阻塞server (测试server)
- anyevent::snmp+coro
- coro学习-击鼓传花
- coro学习1 -并行抓网页
- 最简单的PHP socket echo server。
- 简单的echo server
- java socket通讯之 echo server 和echo client例子
- Socket tips: UDP Echo service - Server code
- Python初体验 —— 一个简单的socket echo server
- AfxMessageBox和MessageBox
- WAMPServer默认配置更改-web根目录
- Android反射机制实现与原理
- wed的各种前端打印方法(3)CSS
- bootstrap(boot)启动uboot
- coro::socket+coro::handle echo server(2)-sysread 的改造
- 常用CSS样式
- md5sum
- 如何在jsp里禁止session
- 加载事件js代码
- jquery实现回旋滚动效果
- ListView保存滑动状态
- github
- 分享几款基于jquery不错的时间插件