gyn

Win32下的Perl,无用的select,停滞的Tk,结束吧....

  IT博客网 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  79 随笔 :: 1 文章 :: 36 评论 :: 0 Trackbacks

Tell me why
为什么要写这个有关轮子代码的解析呢?如果是用IO::Socket配合select_read等写的代码,一来需要自己处理客户socket的连接,二来还要整理传入的数据,如此这般使得代码量变得很巨大,对其解析可能会需要很大的工作量,事实上我也大致写过很长的一个。而且这种具有普遍意义的代码任放在哪个平台上其中的内容大多是不会发生变化的,因而很多地方都可整合起来。在另一个极端上来说,如果使用像POE::Component::Server::TCP的组件,虽然可以将代码量控制在一个很小的范围,但是同时也隐藏了绝大多数的细节,对于刚刚接触POE的初学者,这无异于一个神奇的盒子。所以要用夹在中间的轮子代码,先有一个大致的概念,之后再去深究其中的细节。

一拖n的结构
还是老样子,先把代码的大致结构讲一下。和大多数底层的POE程序差不多,一个session拖一屁股事件句柄。
-------------------------------

POE :: Session -> create(
 inline_states 
=>  {
  _start 
=>   \& server_start ,
  server_accepted 
=>   \& server_accepted ,
  client_input 
=>   \& client_input ,
  client_error 
=>   \& client_error ,
  server_error 
=>   \& server_error ,
 }
);

-------------------------------
_start事件建立了一个服务socket,再用ListenAccept轮子监听它。当发现有客户socket连接时,触发了server_accept事件。在该事件中,我们使用ReadWrite轮子来监视客户输入,并将其返回给客户。如果发生意外,根据事故的制造者,分别交予client_error或者server_error处理。其中server_error将销毁ListenAccept轮子,从而停止整个程序。
所以,不一样关键在于有了ListenAccept和ReadWrite两个轮子。前者用来监听客户socket连接,后者用来处理传入的数据并将它发送回去。这在很大程度上节约了代码量,使我们可以集中更多的注意力在业务逻辑上,而又不至于对于其中的具体实现一头雾水。

记忆点
对于这两个轮子,需要牢记的有两点,首先是参数。ListenAccept需要至少三个,分别是Handle、AcceptEvent和ErrorEvent。Handle是监视对象,AcceptEvent是接受连接时触发的事件,到处可见的ErrorEvent则用来处理错误。这三个缺一不可,不然运行会发生错误,至少需要写一个空句柄。ReadWrite也差不多,只是InputEevnt代替了Listenaccept中的AcceptEvent,用来处理客户输入。
第二点要注意的是ARG参数。可以这么认为,ARG0是与轮子具体功能相关的, ARG1则代表了轮子本身的ID。打个比方,因为ListenAccept是用来监听并接受客户连接的,那么ARG0就是被接受了的客户。由于对于轮子的使用经常是跨事件的,所以必须保留对于轮子的引用。ID因其唯一性,所以可以在哈希表中作为键值以保存对轮子的引用。

测试
-------------------------------

# !/usr/bin/perl

use  warnings;
use  strict;

use  POSIX;
use  IO :: Socket ;

my   $sock   =  IO :: Socket :: INET -> NEW(
 PeerHost 
=>   ' 127.0.0.1 ' ,
 PeerPort 
=>   12345 ,
) or 
die   " can't connect to server: $@\n " ;

my  $ word  =   " hello.\nmy name is Jinhao.\nwlecome to POE.\n " ;

$sock -> send ( $word );

$buffer   =   '' ;
$sock -> recv ( $buffer ,  POSIX :: BUFSIZ);

print   $buffer   unless   $buffer  eq  '' ;

$sock -> shutdown ( 0 );

-------------------------------
客户端还是在本地,应用了一个IO::Socket来发送一段带“\n”的数据,之后接受返回并打印结果。可以印证一点,ReadWrite轮子只有在发现换行才起作用,也就是说如果发送的数据的最后不是以“\n”结尾的,那么打印结果会少一段。至于为什么没有发现数据结尾,我想可能跟操作系统有关系。

posted on 2008-05-29 08:29 gyn_tadao 阅读(146) 评论(1)  编辑 收藏 引用 所属分类: perl

评论

# re: 回声服务器的轮子代码解析 2008-06-03 18:01 35u54
<a title="婴儿游泳" href="http://www.njhanteng.com/">婴儿游泳</a>
<a title="网站推广" href="http://www.rudao.com/google.asp/">网站推广</a>
  回复  更多评论
  



标题  
姓名  
主页
验证码 *
内容(提交失败后,可以通过“恢复上次提交”恢复刚刚提交的内容)
 
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
[使用Ctrl+Enter键可以直接提交]
 
相关链接: