﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>IT博客网-gyn-随笔分类-perl</title><link>http://www.cnitblog.com/gyn/category/2447.html</link><description /><language>zh-cn</language><lastBuildDate>Fri, 09 May 2008 05:21:08 GMT</lastBuildDate><pubDate>Fri, 09 May 2008 05:21:08 GMT</pubDate><ttl>60</ttl><item><title>POE状态机入门与进阶</title><link>http://www.cnitblog.com/gyn/archive/2008/05/09/43537.html</link><dc:creator>gyn_tadao</dc:creator><author>gyn_tadao</author><pubDate>Fri, 09 May 2008 03:20:00 GMT</pubDate><guid>http://www.cnitblog.com/gyn/archive/2008/05/09/43537.html</guid><wfw:comment>http://www.cnitblog.com/gyn/comments/43537.html</wfw:comment><comments>http://www.cnitblog.com/gyn/archive/2008/05/09/43537.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/gyn/comments/commentRss/43537.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/gyn/services/trackbacks/43537.html</trackback:ping><description><![CDATA[一．前言<br />至于POE的应用，我不想多说什么，因为需要使用状态机的地方太多。举一个极端的例子，windows下的perl-tk对于多线程的支持极不稳定，如果在其中加入一个大数据量的处理应用，结果往往会是一个无法动弹的程序。这时除了使用POE，也许没有更好的解决办法了。<br />另外，python中有叫twisted的类似框架，被广泛地应用在网络服务中，具体的使用方法可以参考Oreilly出版的《Python Twisted Network Programming Essentials》。某种意义上，也说明了状态机的重要性。<br /><br />二．基本原理与概念<br /><br />在详细说明POE服务器的建立步骤之前，需要对POE的原理做一个大致的了解。在这个阶段中，我们将描述这方面的不同概念，以及它们在POE中的应用。<br /><br />1. 事件与事件句柄<br />POE 是一个为网络工作和并行任务服务的事件驱动框架。首先作为前提，需要掌握事件和事件驱动编程的意义。<br />在抽象意义上，事件就是真实世界中发生的一件事情。比如说：早晨打铃、面包从烤机里弹出、茶煮好了等。而在用户界面上最常见的事件则是鼠标移动、按钮点击和键盘敲打等等。<br />具体到程序软件事件，则往往是一些抽象的事件。也就是说，它不仅包括了发送给程序的外部活动，而且也包括了一些在操作系统内部运行的事件。比如说，计时器到点了，socket建立了连接，下载完成等。<br />在事件驱动程序中，中心分配器的作用是将事件分配给不同的处理程序。这些处理程序就是事件句柄，顾名思义，它们的任务就是处理相应事件。<br />POE的事件句柄之间的关系是合作性质的。没有两个句柄会同时运行，每一个句柄在被激发运行期间将独占程序。通过尽可能快地返回来保证程序的其它部分得以顺畅运行，这就是事件句柄之间的合作方式。<br /><br />2. POE程序的组成部分<br />最简单的POE程序包括两个模块和一些用户代码：它们分别是POE::Kernel，POE::Session以及一些事件句柄。<br /><br />a. POE::Kernel：<br />POE::Kernel提供了基于事件的操作系统核心服务。包括I/O事件、警报和其它计时事件、信号事件和一些不被人意识到的事件。POE::Kernel提供不同的方法对这些事件进行设置，比如select_read(), delay()和sig()。<br />POE::Kernel还能够跟踪事件发生源和与之相关的任务之间的关系。之所以能够这么做，是因为当事件发生时，它将跟踪哪个任务被激活了。于是它便知道了哪个任务调用方法来使用了这些资源，而这些都是自动完成的。<br />POE::Kernel也知道何事需将任务销毁。它检测任务以确定是否还有事件需要处理，或者是哪个事需要释放占用的资源。当任务没有事件可以触发的时候，POE::Kernel就自动销毁该资源。<br />POE::Kernel会在最后一个session停止以后终止运行。<br /><br />b. POE::Session：<br />POE::Session实例就是上面所讲的由POE::Kernel管理的“任务”。（以下的章节中为了便于识别将使用“session”）<br />每一个session都有一个自己私有的存储空间，叫“heap”。存储在当前session的heap中的数据很难被一个外部session得到。<br />每一个session还拥有自己的资源和事件句柄。这些资源为拥有它们的session生成事件，而事件只被指派到其所处的session中。举例说明，有多个session都可以设置相同的警报，并且任何一个都能接受其所请求的计时事件。但所有其他session不会在意发生在它们之外的事情。<br /><br />c. 事件句柄：<br />事件句柄就是Perl程序。它们因为使用了POE::Kernel传递的参数而不同于一般的perl程序。<br />POE::Kernel是通过@_来传递参数。该数组的前七个成员定义了发生该事件的session的上下文。它包括了一个指向POE::Kernel运行实例的引用、事件自身的名字、指向私有heap的引用以及指向发出事件的session的引用。<br />@_中剩下的成员属于事件自身，其中的具体内容依照被指派的事件类型而定。举例说明：对于I/O事件，包括两个参数：一个是缓冲文件句柄，另一个是用来说明采取何种行为（input、output或者异常）的标记。<br />POE不强求程序员为每一个事件句柄分配所有的参数，要不然这将变成一件非常烦人的工作，因为它们中的一些参数是不常被用到的。而POE::Session会自动为@_输出剩余的常量，这样就能使我们相对比较轻松地将注意力放在重要的参数上，而让POE来处理不必需的参数。<br />POE还允许改变参数的顺序和数量，而不会对程序造成影响。比如说，KERNEL，HEAP和ARG0分别是POE::Kernel实例、当前session的堆栈和事件的第一个用户参数。它们可以一个个直接从@_被导出。<br />my $kernel = $_[KERNEL];<br />my $heap = $_[HEAP];<br />my $thingy = $_[ARG0];<br />或者一次性以队列片段的形式赋值给程序参数。<br />my ( $kernel, $heap, $thingy ) = @_[KERNEL, HEAP, ARG0];<br />当然在事件句柄中我们也可以直接使用$_[KERNEL]，$_[HEAP]和$_[AG0]。但是因为诸如ARG0的参数很难从字面上知道它在事件中代表的真实意义, 所以我们不提倡直接使用这种做法。<br /><br />三．简单的POE例子<br />现在大致知道了POE编程的概念，我们将举若干例子来了解它到底是怎么运行的。<br /><br />1. 一个单session的例子<br />简单的POE程序包括三个部分：一个用来加载模块和配置条件的前端，初始化并且运行一个或者多个session的主体和用来描述事件句柄的具体程序。<br /><br />a. 前端：<br />#!/usr/bin/perl<br /><br />use warnings;<br />use strict;<br />use POE;<br />引入POE模块的过程的背后隐藏了一些细节，事实上这么做还加载了一些诸如POE::Kernel和POE:Sesson的模块并相应地做了一些初始化，而通常在每个POE程序中我们都会用到这些隐藏模块。<br />在POE::Kernel第一次被引入时，它生成了一个将贯穿整个程序POE::Kernel实例。POE::Session会根据不同的事件输出默认常量给事件句柄的某些参数，如：KERNEL，HEAP，ARG0等等。<br />所以一个简单的use POE为程序做了大量的初始化工作。<br /><br />b. 主体session：<br />当所有的条件都准备好之后，为了保证POE::Kernel的有效运行，我们必须建立至少一个session。不然的话，运行程序意味着无事可做。<br />在这个例子里，我们将建立一个包含_start，_stop和count这三个事件的任务。POE::Session将每个事件与一个句柄联系在一起。<br />POE::Session-&gt;create{<br />    Inline_states =&gt; {<br />        _start =&gt; \&amp;session_start,<br />        _stop =&gt; \&amp;session_stop,<br />        count =&gt; \&amp;session_count,<br />    }<br />};<br />前两个事件是由POE::Kernel自身所提供的。它们分别表示该session的启动和销毁。最后一个事件是用户自定义事件，它被用于程序的逻辑之中。<br />我们之所以没有为session保留一个引用的原因是因为该session会自动被注册到POE::Kernel中，并接收它的管理，而我们在程序是很少直接使用该session的。<br />事实上，保存一个session的应用是存在危险的。因为如果存在显式的引用，Perl将不会自动销毁session对象或者重新为其分配内存。<br />接着我们启动POE::Kernel，由此便建立了一个用来探测并分派事件的主循环。在此示例程序中，为了使运行结果更加明确，我们将注明POE::Kernel运行的开始处和结束点。<br />print “Starting POE::Kernel.\n”;<br />POE::Kernel-&gt;run();<br />print “POE::Kernle’s run method returned.\n”;<br />exit;<br />Kernel的run方法只有在所有session返回之后才会停止循环。之后，我们调用一个表示程序结束的提示符的exit系统方法来表示程序被终止，而在实际的应用中这么做是不必要的。<br /><br />c. 事件句柄：<br />下面我们来了解一下事件句柄的应用，首先从_start开始。_start的句柄将在sesson初始化完成之后开始运行，session在其自身的上下文中使用它来实现输入引导。比如初始化heap中的值，或者分配一些必要的资源等等。<br />在该句柄中我们建立了一个累加器，并且发出了“count”事件以触发相应的事件句柄。<br />sub session_start {<br />    print "Session ", $_[SESSION]-&gt;ID, " has started.\n";<br />    $_[HEAP]-&gt;{count} = 0;<br />    $_[KERNEL]-&gt;yield("count");<br />}<br />一些熟悉线程编程的人可能会对yield方法在这里的使用产生困惑。事实上，它并不是用来中止session运行的，而是将一个事件放入fifo分派队列的末尾处，当队列中在其之前的事件被处理完毕之后，该事件将被触发以运行相应的事件句柄。这个概念在多任务环境下更容易被理解。我们可以通过在调用yield方法之后立即返回的办法，来清晰地体现yield方法的行为。<br />接下来的是_stop句柄。POE::Kernel将在所有session再无事件可触发之后，并且是在自身被销毁之前调用它。<br />sub session_stop {<br />    print "Session ", $_[SESSION]-&gt;ID, " has stopped.\n";<br />}<br />在_stop中设置一个事件是无用的。销毁session的过程本身包括清理与之相关的资源，而事件就是资源的组成部分。所以对于所有在_stop中的事件，在其能够被分派之前都是将被清理的。<br />最后讲一下count事件句柄。该函数用来增加heap中的累加器计数，并打印累加结果。我们可以使用一个while来完成这件工作，但是用yield方法一来可以使得程序更短小精悍，二来还能够加深对POE事件处理原理的理解。<br />sub session_count {<br />    my ( $kernel, $heap ) = @_[ KERNEL, HEAP ];<br />    my $session_id = $_[SESSION]-&gt;ID;<br /><br />    my $count = ++$heap-&gt;{count};<br />    print "Session $session_id has counted to $count.\n";<br /><br />    $kernel-&gt;yield("count") if $count &lt; 10;<br />}<br />该函数的最后一句表示：只要累加器计数未超过10，session将再yield一个count事件。因为不断地触发了session_count句柄，使得当前session可以继续得以生存而不会被POE::Kernel清理。<br />当计数器到10时，便不再调用yield命令，session也将停止。一旦POE::Kernel检测到该session再没有事件句柄可被激发，便在调用_stop事件句柄之后将其清理销毁。<br />以下是运行的结果：<br />  Session 2 has started.<br />  Starting POE::Kernel.<br />  Session 2 has counted to 1.<br />  Session 2 has counted to 2.<br />  Session 2 has counted to 3.<br />  Session 2 has counted to 4.<br />  Session 2 has counted to 5.<br />  Session 2 has counted to 6.<br />  Session 2 has counted to 7.<br />  Session 2 has counted to 8.<br />  Session 2 has counted to 9.<br />  Session 2 has counted to 10.<br />  Session 2 has stopped.<br />  POE::Kernel's run() method returned.<br />对于该结果有几点需要解释一下。<br />?    为什么在运行结果中session的id是2。因为通常情况下，POE::Kernel是最先被创建的，它的id号会是1。接下来创建session的id号依次被累加。<br />?    因为当运行POE::Session-&gt;create时就会分派_start事件，所以_start事件句柄的激发是在POE::Kernel运行之前的。<br />?    第一个count事件句柄并没有被立即处理。这是因为该事件被Kernel放入了分派队列之中。<br />?    导致session停止的原因除了再没有事件可触发而之外，外部的终止信号也可以用来停止session。<br /><br />2．多任务的POE例子<br /><br />可以将以上的这个计数程序做成多任务的形式，使每一个session将在其自身的heap中保存累加器。各个session的事件被依次传送到POE::Kernel的事件队列中，并以先进先出的形式进行处理，以保证这些事件将轮流被执行。<br />为了演示这个结果，我们将复制以上程序中的session部分，其它部分保持原样不变。<br />for ( 1 .. 2 ) {<br />    POE::Session-&gt;create(<br />        inline_states =&gt; {<br />            _start =&gt; \&amp;session_start,<br />            _stop  =&gt; \&amp;session_stop,<br />            count  =&gt; \&amp;session_count,<br />          }<br />    );<br />}<br />以下便是修改后的程序的运行结果：<br />  Session 2 has started.<br />  Session 3 has started.<br />  Starting POE::Kernel.<br />  Session 2 has counted to 1.<br />  Session 3 has counted to 1.<br />  Session 2 has counted to 2.<br />  Session 3 has counted to 2.<br />  Session 2 has counted to 3.<br />  Session 3 has counted to 3.<br />  Session 2 has counted to 4.<br />  Session 3 has counted to 4.<br />  Session 2 has counted to 5.<br />  Session 3 has counted to 5.<br />  Session 2 has counted to 6.<br />  Session 3 has counted to 6.<br />  Session 2 has counted to 7.<br />  Session 3 has counted to 7.<br />  Session 2 has counted to 8.<br />  Session 3 has counted to 8.<br />  Session 2 has counted to 9.<br />  Session 3 has counted to 9.<br />  Session 2 has counted to 10.<br />  Session 2 has stopped.<br />  Session 3 has counted to 10.<br />  Session 3 has stopped.<br />  POE::Kernel's run() method returned.<br />每一个session是在自身heap中保存计数数据的，这与我们建立的session实例数量无关。POE轮次处理每一个事件，每次只有一个事件句柄被运行。当事件句柄运行的时候，POE::Kernel自身也将被中断，在事件句柄返回之前，没有事件被分派。<br />当各个session的事件被传送到主程序事件队列后，位于队列头部的事件被首先处理，新来的事件将被放置在队列的尾部。以此保证队列的轮次处理。<br />POE::Kernek的run方法在最后一个session停止之后返回。<br /><br />四．回声服务器<br />最后我们将用IO::Select建立一个非派生的回声服务器，然后再利用多个抽象层的概念将它移植到POE上。<br /><br />1. 一个简单的select()服务器<br />这个非派生的服务器的原型来自于《Perl Cookbook》中的17.13章节。为了保持简洁并且也是为了更方便于移植到POE上，对其做了一些修改。同时为了增加可读性，还给该服务器设定一些小的目的和功能。<br />首先，需要引入所需的模块并初始化一些数据结构。<br />#!/usr/bin/perl<br /><br />use warnings;<br />use strict;<br /><br />use IO::Socket;<br />use IO::Select;<br />use Tie::RefHash;<br /><br />my %inbuffer  = ();<br />my %outbuffer = ();<br />my %ready = ();<br /><br />tie %ready, "Tie::RefHash";<br />接下来，我们要建立一个服务器socket。为了不阻塞单进程的服务器，这个socket被设置为非阻塞状态。<br />my $server = IO::Socket::INET-&gt;new<br />  ( LocalPort =&gt; 12345,<br />    Listen =&gt; 10,<br />  ) or die "can't make server socket: $@\n";<br /><br />$server-&gt;blocking(0);<br />然后建立主循环。我们制造一个IO::Socket对象用以监视socket上的活动。无论何时，当有一个事件发生在socket上，都会有相应的程序来处理它。<br />my $select = IO::Select-&gt;new($server);<br /><br />while (1) {<br />    foreach my $client ( $select-&gt;can_read(1) ) {<br />        handle_read($client);<br />    }<br /><br />    foreach my $client ( keys %ready ) {<br />        foreach my $request ( @{ $ready{$client} } ) {<br />            print "Got request: $request";<br />            $outbuffer{$client} .= $request;<br />        }<br />        delete $ready{$client};<br />    }<br /><br />    foreach my $client ( $select-&gt;can_write(1) ) {<br />        handle_write($client);<br />    }<br />}<br /><br />exit;<br />以上的主循环对整个程序做了一个大致的总结。下面是用于处理socket不同行为的几个函数。<br />第一个函数用来处理可读状态的socket。如果这个准备就绪的socket是服务器的socket，我们再接收一个新的连接，并将它注册到IO::Socket对象中。如果这是一个存在输入数据的客户端socket，我们读取数据并对其进行处理，并将处理的结果添加到%ready数据结构中。主循环会捕获在%ready中的数据，并将它们回传给客户端。<br />sub handle_read {<br />    my $client = shift;<br /><br />    if ( $client == $server ) {<br />        my $new_client = $server-&gt;accept();<br />        $new_client-&gt;blocking(0);<br />        $select-&gt;add($new_client);<br />        return;<br />    }<br /><br />    my $data = "";<br />    my $rv   = $client-&gt;recv( $data, POSIX::BUFSIZ, 0 );<br /><br />    unless ( defined($rv) and length($data) ) {<br />        handle_error($client);<br />        return;<br />    }<br /><br />    $inbuffer{$client} .= $data;<br />    while ( $inbuffer{$client} =~ s/(.*\n)// ) {<br />        push @{ $ready{$client} }, $1;<br />    }<br />}<br />接下来是一个处理可写状态的socket的函数。等待被发送到客户端的数据将被写到这个socket中，之后被从输出缓冲中删除。<br />sub handle_write {<br />    my $client = shift;<br /><br />    return unless exists $outbuffer{$client};<br /><br />    my $rv = $client-&gt;send( $outbuffer{$client}, 0 );<br />    unless ( defined $rv ) {<br />        warn "I was told I could write, but I can't.\n";<br />        return;<br />    }<br /><br />    if ( $rv == length( $outbuffer{$client} ) or<br />        $! == POSIX::EWOULDBLOCK<br />      ) {<br />        substr( $outbuffer{$client}, 0, $rv ) = "";<br />        delete $outbuffer{$client} unless length $outbuffer{$client};<br />        return;<br />    }<br /><br />    handle_error($client);<br />}<br />最后我们需要一个程序来处理客户socket在读取和发送数据时产生的错误。它会为发生错误的socket做一些清理工作，并保证它们被正确关闭。<br />sub handle_error {<br />    my $client = shift;<br /><br />    delete $inbuffer{$client};<br />    delete $outbuffer{$client};<br />    delete $ready{$client};<br /><br />    $select-&gt;remove($client);<br />    close $client;<br />}<br />短短130行代码，我们就有了一个简单的回声服务器。不算太坏，但是我们可以做得更好。<br /><br />2. 将服务器移植到POE上<br />为了把IO::Socket服务器移植到POE上，需要使用到某些POE的底层特征。为了详细说明的需要，我们竟可能地不省略细节，而最终的程序也将保留其中的大部分代码。<br />事实上，以上的IO::Socket服务器本身就是由事件驱动的，在其中包含了一个用于检测并分派之间的主循环，配以处理这些事件的相应事件句柄。从这一点上来说，与POE的原理和架构有异曲同工的意思。<br />新的服务器程序需要一个如下所示的POE空框架。用于具体功能实现的代码将被添加到这个框架之中。<br />#!/usr/bin/perl<br /><br />use warnings;<br />use strict;<br /><br />use POSIX;<br />use IO::Socket;<br />use POE;<br /><br />POE::Session-&gt;create<br />  ( inline_states =&gt;<br />      {<br />      }<br />  );<br /><br />POE::Kernel-&gt;run();<br />exit;<br />在继续完成接下来的程序之前，为了勾勒出程序的大致框架结构，必须明确哪些事件的出现是必要的。<br />?    服务器启动，完成初始化。<br />?    服务器socket准备就绪，可以接收连接。<br />?    客户socket处于可读取状态，服务器读取数据并对其进行处理。<br />?    客户socket处于可写状态，服务器对其写入一些数据。<br />?    客户socket发生错误，需要将其关闭。<br />一旦知道了需要做些什么，就可以建立这些事件的名称，并为这些事件编写相应的事件处理句柄，从而快速地完成POE::Session的构造。<br />POE::Session-&gt;create<br />  ( inline_states =&gt;<br />      { _start =&gt; \&amp;server_start,<br />        event_accept =&gt; \&amp;server_accept,<br />        event_read   =&gt; \&amp;client_read,<br />        event_write  =&gt; \&amp;client_write,<br />        event_error  =&gt; \&amp;client_error,<br />      }<br />  );<br />现在是真正将IO::Select代码移植过来的时候了！和IO::Select服务器相同，需要为客户socket提供输入和输出缓冲，而且由于这两个缓冲对socket句柄的重要性并且不存在冲突，它们将被保持为程序的全局变量。另外，在这里将不再使用%ready哈希表。<br />my %inbuffer  = ();<br />my %outbuffer = ();<br />紧接着是引入IO::Select的程序片段，因为每一段都是上面指定的事件所触发的，因此这些片段将被移植入相应事件的处理句柄中。<br />在_start事件的处理句柄中，需要建立一个服务器的监听socket，并用select_read为其分配一个事件发生器。句柄中用到的POE::Kernel模块中的select_read方法接收两个参数：第一个是需要监视的socket，第二个是当该socket处于可读状态时所触发的处理句柄。<br />sub server_start {<br />    my $server = IO::Socket::INET-&gt;new<br />      ( LocalPort =&gt; 12345,<br />        Listen =&gt; 10,<br />        Reuse  =&gt; "yes",<br />      ) or die "can't make server socket: $@\n";<br /><br />    $_[KERNEL]-&gt;select_read( $server, "event_accept" );<br />}<br />注意一点，我们并没有保存服务器socket。因为POE::Kernel会对其进行跟踪，并将其作为一个参数传递给event_accept事件句柄。只有在需要特殊用途的情况下，我们才会保存一个该socket的拷贝。<br />再回顾POE::Session构造器，事件event_accept会激发server_accept事件句柄。该句柄接收一个新的客户socket，并对其分配一个监视器。<br />sub server_accept {<br />    my ( $kernel, $server ) = @_[ KERNEL, ARG0 ];<br /><br />    my $new_client = $server-&gt;accept();<br />    $kernel-&gt;select_read( $new_client, "event_read" );<br />}<br />之后我们在client_read句柄中处理处理来自客户的数据。当新连接的客户socket处于可读状态时，句柄被触发。该句柄中的第一个客户参数即为所连接的客户socket，因此我们无需再为其保留一个拷贝。<br />在内容上，句柄client_read与IO::Select服务器中的handle_read几乎一样。而由于handle_read的accept部分的内容被移植到了server_accept句柄中，相应地就不再需要%ready哈希表了。<br />如果接收过程发生错误，客户socket通过POE::Kernel的yield方法将被传送到event_error句柄中。因为该yield方法是根据程序员的具体要求发送事件的，所以需要在yield中将发生错误的客户socket作为某个参数，而此socket在处理该event_error的事件句柄client_error中被赋值给$_[ARG0]。<br />接着，如果在client_read中发现输出缓存存在数据，我们将检测以保证当该客户socket处于可写状态时，及时触发事件处理句柄，将数据发送出去。<br />sub client_read {<br />    my ( $kernel, $client ) = @_[ KERNEL, ARG0 ];<br /><br />    my $data = "";<br />    my $rv   = $client-&gt;recv( $data, POSIX::BUFSIZ, 0 );<br /><br />    unless ( defined($rv) and length($data) ) {<br />        $kernel-&gt;yield( event_error =&gt; $client );<br />        return;<br />    }<br /><br />    $inbuffer{$client} .= $data;<br />    while ( $inbuffer{$client} =~ s/(.*\n)// ) {<br />        $outbuffer{$client} .= $1;<br />    }<br /><br />    if ( exists $outbuffer{$client} ) {<br />        $kernel-&gt;select_write( $client, "event_write" );<br />    }<br />}<br />在用于发送数据的事件句柄中，第一个客户参数依然是一个可用的socket。在该句柄中，如果输出缓存为空，则停止检测并迅速返回。否则，我们将试图将缓冲内的数据全部发出。如果所有数据均发送成功，该缓冲将被销毁。与client_read类似，client_write中也有相应的错误处理句柄。<br />sub client_write {<br />    my ( $kernel, $client ) = @_[ KERNEL, ARG0 ];<br /><br />    unless ( exists $outbuffer{$client} ) {<br />        $kernel-&gt;select_write($client);<br />        return;<br />    }<br /><br />    my $rv = $client-&gt;send( $outbuffer{$client}, 0 );<br />    unless ( defined $rv ) {<br />        warn "I was told I could write, but I can't.\n";<br />        return;<br />    }<br /><br />    if ( $rv == length( $outbuffer{$client} ) or<br />        $! == POSIX::EWOULDBLOCK<br />      ) {<br />        substr( $outbuffer{$client}, 0, $rv ) = "";<br />        delete $outbuffer{$client} unless length $outbuffer{$client};<br />        return;<br />    }<br /><br />    $kernel-&gt;yield( event_error =&gt; $client );<br />}<br />最后说明一下在以上两个句柄中被用到的错误处理句柄。我们首先删除了客户socket的输入输出缓存，再关闭建立在该socket上的所有监视，最后保证该socket被成功关闭。如此这般便有效地关闭了来自于客户的连接。<br />sub client_error {<br />    my ( $kernel, $client ) = @_[ KERNEL, ARG0 ];<br /><br />    delete $inbuffer{$client};<br />    delete $outbuffer{$client};<br /><br />    $kernel-&gt;select($client);<br />    close $client;<br />}<br />移植成功！<br /><img src ="http://www.cnitblog.com/gyn/aggbug/43537.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/gyn/" target="_blank">gyn_tadao</a> 2008-05-09 11:20 <a href="http://www.cnitblog.com/gyn/archive/2008/05/09/43537.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>多看代码是提高能力的捷径</title><link>http://www.cnitblog.com/gyn/archive/2008/05/04/43297.html</link><dc:creator>gyn_tadao</dc:creator><author>gyn_tadao</author><pubDate>Sun, 04 May 2008 08:36:00 GMT</pubDate><guid>http://www.cnitblog.com/gyn/archive/2008/05/04/43297.html</guid><wfw:comment>http://www.cnitblog.com/gyn/comments/43297.html</wfw:comment><comments>http://www.cnitblog.com/gyn/archive/2008/05/04/43297.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/gyn/comments/commentRss/43297.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/gyn/services/trackbacks/43297.html</trackback:ping><description><![CDATA[最近一直有在学习POE，这是一个类似于状态机的网络框架，在python上有叫twisted的类似框架。为此也看了一些文章，并学习了一些例子。<br />对于SOCKET编程，也许是很久没有用了的缘故，看到相关的一段程序时，感觉相当地眼生。还因为之前一直是用perl原生的socket命令来写的，所以对IO::Socket没有做过多的了解。再去看书，或者将perldoc里的内容从头到尾地通读一遍，一来没有什么兴趣，二来就以往经验来看很多内容都是很少用到的，看了也容易忘记。所以就将这段代码抄了一遍，对于其中不了解或者有疑问的再去查perldoc，或者写一些测试代码来验证。事实证明收获也是不小，很快就了解了其中的主要内容，顺带地还将POSIX中的一些常量搞搞清楚。更重要的是在抄写这样规范的代码，对于自身编写程序的格式也会有潜移默化的影响。<br />这么做的关键在于，首先要有一段好的代码，第二不要抱着得过且过的心态放过一些细节。<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 128, 0);">#</span><span style="color: rgb(0, 128, 0);">!/usr/bin/perl</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 0, 255);">use</span><span style="color: rgb(0, 0, 0);"> warnings;<br /></span><span style="color: rgb(0, 0, 255);">use</span><span style="color: rgb(0, 0, 0);"> strict;<br /><br /></span><span style="color: rgb(0, 0, 255);">use</span><span style="color: rgb(0, 0, 0);"> POSIX;<br /></span><span style="color: rgb(0, 0, 255);">use</span><span style="color: rgb(0, 0, 0);"> IO</span><span style="color: rgb(0, 0, 0);">::</span><span style="color: rgb(0, 0, 255);">Socket</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 0, 255);">use</span><span style="color: rgb(0, 0, 0);"> IO</span><span style="color: rgb(0, 0, 0);">::</span><span style="color: rgb(0, 0, 255);">Select</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 0, 255);">use</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">Tie</span><span style="color: rgb(0, 0, 0);">::</span><span style="color: rgb(0, 0, 0);">RefHash;<br /><br /></span><span style="color: rgb(0, 128, 0);">#</span><span style="color: rgb(0, 128, 0);"> Create the server socket.</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 0, 255);">my</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$server</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> IO</span><span style="color: rgb(0, 0, 0);">::</span><span style="color: rgb(0, 0, 255);">Socket</span><span style="color: rgb(0, 0, 0);">::</span><span style="color: rgb(0, 0, 0);">INET</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">new(<br />        LocalPort </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">12345</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"><br />        </span><span style="color: rgb(0, 0, 255);">Listen</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">10</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"><br />    ) or </span><span style="color: rgb(0, 0, 255);">die</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">can't make server socket: $@\n</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">;<br />    <br /></span><span style="color: rgb(128, 0, 128);">$server</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">blocking(</span><span style="color: rgb(128, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">);<br /><br /></span><span style="color: rgb(0, 128, 0);">#</span><span style="color: rgb(0, 128, 0);"> Set structures to track input and output data.</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 0, 255);">my</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">%inbuffer</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> ();<br /></span><span style="color: rgb(0, 0, 255);">my</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">%outbuffer</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> ();<br /></span><span style="color: rgb(0, 0, 255);">my</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">%ready</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> ();<br /><br /></span><span style="color: rgb(0, 0, 255);">tie</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">%ready</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">Tie::RefHash</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">;<br /><br /></span><span style="color: rgb(0, 128, 0);">#</span><span style="color: rgb(0, 128, 0);"> The select loop itself.</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(128, 0, 128);">$my</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">select</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> IO</span><span style="color: rgb(0, 0, 0);">::</span><span style="color: rgb(0, 0, 255);">Select</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">new(</span><span style="color: rgb(128, 0, 128);">$server</span><span style="color: rgb(0, 0, 0);">);<br /><br /></span><span style="color: rgb(0, 0, 255);">while</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(128, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">) {<br />    <br />    </span><span style="color: rgb(0, 128, 0);">#</span><span style="color: rgb(0, 128, 0);"> Process sockets that are ready for reading.</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">my</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$client</span><span style="color: rgb(0, 0, 0);">( </span><span style="color: rgb(128, 0, 128);">$select</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">can_read(</span><span style="color: rgb(128, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">) ) {<br />        handle_read(</span><span style="color: rgb(128, 0, 128);">$client</span><span style="color: rgb(0, 0, 0);">);<br />    }<br />    <br />    </span><span style="color: rgb(0, 128, 0);">#</span><span style="color: rgb(0, 128, 0);"> Process any complete requests. Echo the data back to the client,<br />    # by putting the ready lines into the client's output buffer.</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">my</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$client</span><span style="color: rgb(0, 0, 0);"> ( </span><span style="color: rgb(0, 0, 255);">keys</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">%ready</span><span style="color: rgb(0, 0, 0);"> ) {<br />        </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">my</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$request</span><span style="color: rgb(0, 0, 0);"> ( @{ </span><span style="color: rgb(128, 0, 128);">$ready</span><span style="color: rgb(0, 0, 0);">{</span><span style="color: rgb(128, 0, 128);">$client</span><span style="color: rgb(0, 0, 0);">} } ) {<br />            </span><span style="color: rgb(0, 0, 255);">print</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">Got request: $request\n</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">;<br />            </span><span style="color: rgb(128, 0, 128);">$outbuffer</span><span style="color: rgb(0, 0, 0);">{</span><span style="color: rgb(128, 0, 128);">$client</span><span style="color: rgb(0, 0, 0);">} </span><span style="color: rgb(0, 0, 0);">.=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$request</span><span style="color: rgb(0, 0, 0);">;<br />        }<br />        </span><span style="color: rgb(0, 0, 255);">delete</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$ready</span><span style="color: rgb(0, 0, 0);">{</span><span style="color: rgb(128, 0, 128);">$client</span><span style="color: rgb(0, 0, 0);">};<br />    }<br />    <br />    </span><span style="color: rgb(0, 128, 0);">#</span><span style="color: rgb(0, 128, 0);"> Process sockets that are ready for writing.</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">my</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$client</span><span style="color: rgb(0, 0, 0);"> ( </span><span style="color: rgb(128, 0, 128);">$server</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">can_write(</span><span style="color: rgb(128, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">) ) {<br />        handle_write(</span><span style="color: rgb(128, 0, 128);">$client</span><span style="color: rgb(0, 0, 0);">);<br />    }<br />}<br /><br /></span><span style="color: rgb(0, 0, 255);">exit</span><span style="color: rgb(0, 0, 0);">;<br /><br /></span><span style="color: rgb(0, 128, 0);">#</span><span style="color: rgb(0, 128, 0);"> Handle a socket that's ready to be read from.</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 0, 255);">sub</span><span style="color: rgb(0, 0, 0);"> handle_read {<br />    </span><span style="color: rgb(0, 0, 255);">my</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$client</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">shift</span><span style="color: rgb(0, 0, 0);">;<br />    <br />    </span><span style="color: rgb(0, 128, 0);">#</span><span style="color: rgb(0, 128, 0);"> If it's the server socket, accept a new client connection.</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> ( </span><span style="color: rgb(128, 0, 128);">$client</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$server</span><span style="color: rgb(0, 0, 0);"> ) {<br />        </span><span style="color: rgb(0, 0, 255);">my</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$new_client</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$server</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 255);">accept</span><span style="color: rgb(0, 0, 0);">();<br />        </span><span style="color: rgb(128, 0, 128);">$new_client</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">blocking(</span><span style="color: rgb(128, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">);<br />        </span><span style="color: rgb(128, 0, 128);">$select</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">add(</span><span style="color: rgb(128, 0, 128);">$new_client</span><span style="color: rgb(0, 0, 0);">);<br />        </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">;<br />    }<br />    <br />    </span><span style="color: rgb(0, 128, 0);">#</span><span style="color: rgb(0, 128, 0);"> Read from an established client socket.</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">my</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$data</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">""</span><span style="color: rgb(0, 0, 0);">;<br />    </span><span style="color: rgb(0, 0, 255);">my</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$rv</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$client</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 255);">recv</span><span style="color: rgb(0, 0, 0);">( </span><span style="color: rgb(128, 0, 128);">$data</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> POSIX</span><span style="color: rgb(0, 0, 0);">::</span><span style="color: rgb(0, 0, 0);">BUFSIZ</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">0</span><span style="color: rgb(0, 0, 0);"> );<br />    <br />    </span><span style="color: rgb(0, 128, 0);">#</span><span style="color: rgb(0, 128, 0);"> Handle socket errors.</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">unless</span><span style="color: rgb(0, 0, 0);"> ( </span><span style="color: rgb(0, 0, 255);">defined</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(128, 0, 128);">$rv</span><span style="color: rgb(0, 0, 0);">) and </span><span style="color: rgb(0, 0, 255);">length</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(128, 0, 128);">$data</span><span style="color: rgb(0, 0, 0);">) ) {<br />        handle_error(</span><span style="color: rgb(128, 0, 128);">$client</span><span style="color: rgb(0, 0, 0);">);<br />        </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">;<br />    }<br />    <br />    </span><span style="color: rgb(0, 128, 0);">#</span><span style="color: rgb(0, 128, 0);"> Successful read. Buffer the data we got, and parse it into lines.<br />    # Place the lines into %ready, where they will be processed later.</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(128, 0, 128);">$inbuffer</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(128, 0, 128);">$client</span><span style="color: rgb(0, 0, 0);">) </span><span style="color: rgb(0, 0, 0);">.=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$data</span><span style="color: rgb(0, 0, 0);">;<br />    </span><span style="color: rgb(0, 0, 255);">while</span><span style="color: rgb(0, 0, 0);"> ( </span><span style="color: rgb(128, 0, 128);">$inbuffer</span><span style="color: rgb(0, 0, 0);">{</span><span style="color: rgb(128, 0, 128);">$client</span><span style="color: rgb(0, 0, 0);">} </span><span style="color: rgb(0, 0, 0);">=~</span><span style="color: rgb(0, 0, 0);"> s</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">.*\</span><span style="color: rgb(0, 0, 0);">n)</span><span style="color: rgb(0, 0, 0);">//</span><span style="color: rgb(0, 0, 0);"> ) {<br />        </span><span style="color: rgb(0, 0, 255);">push</span><span style="color: rgb(0, 0, 0);"> @{ </span><span style="color: rgb(128, 0, 128);">$ready</span><span style="color: rgb(0, 0, 0);">{</span><span style="color: rgb(128, 0, 128);">$client</span><span style="color: rgb(0, 0, 0);">} }</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> $</span><span style="color: rgb(128, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">;<br />    }<br />}<br /><br /></span><span style="color: rgb(0, 128, 0);">#</span><span style="color: rgb(0, 128, 0);"> Handle a socket that's ready to be write to.</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 0, 255);">sub</span><span style="color: rgb(0, 0, 0);"> handle_write {<br />    </span><span style="color: rgb(0, 0, 255);">my</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$client</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">shift</span><span style="color: rgb(0, 0, 0);">;<br />    <br />    </span><span style="color: rgb(0, 128, 0);">#</span><span style="color: rgb(0, 128, 0);"> Skip this client if there's nothing write.</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">unless</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">exists</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$outbuffer</span><span style="color: rgb(0, 0, 0);">{</span><span style="color: rgb(128, 0, 128);">$client</span><span style="color: rgb(0, 0, 0);">};<br />    <br />    </span><span style="color: rgb(0, 128, 0);">#</span><span style="color: rgb(0, 128, 0);"> Attempt to write pending data to the client.</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">my</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$rv</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$client</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 255);">send</span><span style="color: rgb(0, 0, 0);">( </span><span style="color: rgb(128, 0, 128);">$outbuffer</span><span style="color: rgb(0, 0, 0);">{</span><span style="color: rgb(128, 0, 128);">$client</span><span style="color: rgb(0, 0, 0);">}</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">0</span><span style="color: rgb(0, 0, 0);"> );<br />    </span><span style="color: rgb(0, 0, 255);">unless</span><span style="color: rgb(0, 0, 0);"> ( </span><span style="color: rgb(0, 0, 255);">defined</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$rv</span><span style="color: rgb(0, 0, 0);"> ) {<br />        </span><span style="color: rgb(0, 0, 255);">warn</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">I was told I could write, but I can't.\n</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">;<br />        </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">;<br />    }<br />    <br />    </span><span style="color: rgb(0, 128, 0);">#</span><span style="color: rgb(0, 128, 0);"> Successful write. Remove what was sent from the output buffer.</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> ( </span><span style="color: rgb(128, 0, 128);">$rv</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">length</span><span style="color: rgb(0, 0, 0);">( </span><span style="color: rgb(128, 0, 128);">$outbuffer</span><span style="color: rgb(0, 0, 0);">{</span><span style="color: rgb(128, 0, 128);">$client</span><span style="color: rgb(0, 0, 0);">} ) or $</span><span style="color: rgb(0, 0, 0);">!</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);">POSIX</span><span style="color: rgb(0, 0, 0);">::</span><span style="color: rgb(0, 0, 0);">EWORLDBLOCK ) {<br />        </span><span style="color: rgb(0, 0, 255);">substr</span><span style="color: rgb(0, 0, 0);">( </span><span style="color: rgb(128, 0, 128);">$outbuffer</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(128, 0, 128);">$client</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$rv</span><span style="color: rgb(0, 0, 0);"> ) </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">""</span><span style="color: rgb(0, 0, 0);">;<br />        </span><span style="color: rgb(0, 0, 255);">delete</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$outbuffer</span><span style="color: rgb(0, 0, 0);">{</span><span style="color: rgb(128, 0, 128);">$client</span><span style="color: rgb(0, 0, 0);">} </span><span style="color: rgb(0, 0, 255);">unless</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">length</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$outbuffer</span><span style="color: rgb(0, 0, 0);">{</span><span style="color: rgb(128, 0, 128);">$client</span><span style="color: rgb(0, 0, 0);">};<br />        </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">;<br />    }<br />    <br />    </span><span style="color: rgb(0, 128, 0);">#</span><span style="color: rgb(0, 128, 0);"> Otherwise there was an error.</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">    handle_error(</span><span style="color: rgb(128, 0, 128);">$client</span><span style="color: rgb(0, 0, 0);">);<br />}<br /><br /></span><span style="color: rgb(0, 128, 0);">#</span><span style="color: rgb(0, 128, 0);"> Handle client error. Clean up after dead socket.</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 255);">sub</span><span style="color: rgb(0, 0, 0);"> handle_error {<br />    </span><span style="color: rgb(0, 0, 255);">my</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$client</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">shift</span><span style="color: rgb(0, 0, 0);">;<br />    <br />    </span><span style="color: rgb(0, 0, 255);">delete</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$inbuffer</span><span style="color: rgb(0, 0, 0);">{</span><span style="color: rgb(128, 0, 128);">$client</span><span style="color: rgb(0, 0, 0);">};<br />    </span><span style="color: rgb(0, 0, 255);">delete</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$outbuffer</span><span style="color: rgb(0, 0, 0);">{</span><span style="color: rgb(128, 0, 128);">$client</span><span style="color: rgb(0, 0, 0);">};<br />    </span><span style="color: rgb(0, 0, 255);">delete</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$ready</span><span style="color: rgb(0, 0, 0);">{</span><span style="color: rgb(128, 0, 128);">$client</span><span style="color: rgb(0, 0, 0);">};<br />    <br />    </span><span style="color: rgb(128, 0, 128);">$select</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">remove(</span><span style="color: rgb(128, 0, 128);">$client</span><span style="color: rgb(0, 0, 0);">);<br />    </span><span style="color: rgb(0, 0, 255);">close</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$client</span><span style="color: rgb(0, 0, 0);">;<br />}<br /></span></div><br /><img src ="http://www.cnitblog.com/gyn/aggbug/43297.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/gyn/" target="_blank">gyn_tadao</a> 2008-05-04 16:36 <a href="http://www.cnitblog.com/gyn/archive/2008/05/04/43297.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一段视频重录的代码</title><link>http://www.cnitblog.com/gyn/archive/2008/04/07/42051.html</link><dc:creator>gyn_tadao</dc:creator><author>gyn_tadao</author><pubDate>Mon, 07 Apr 2008 03:36:00 GMT</pubDate><guid>http://www.cnitblog.com/gyn/archive/2008/04/07/42051.html</guid><wfw:comment>http://www.cnitblog.com/gyn/comments/42051.html</wfw:comment><comments>http://www.cnitblog.com/gyn/archive/2008/04/07/42051.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/gyn/comments/commentRss/42051.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/gyn/services/trackbacks/42051.html</trackback:ping><description><![CDATA[网站会录制一档每晚播出的电视节目，但是有时候录制会失败，于是需要在第二天重播的时候再次录制。为此，需要调整各个文件的参数，由于参数比较多而且涉及到FTP传输，对于不是很熟悉这一过程的网管，如果一不留神很可能会导致再次失败。所以写了一个带界面的设置工具，完成录制和传输过程。<br /><img src="http://www.cnitblog.com/images/cnitblog_com/gyn/chonglu.JPG" alt="chonglu.JPG" border="0" height="48" width="592" /><br />代码：<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 128, 128);"> 1</span> <span style="color: rgb(0, 0, 255);">use</span><span style="color: rgb(0, 0, 0);"> Win32</span><span style="color: rgb(0, 0, 0);">::</span><span style="color: rgb(0, 0, 0);">GUI;<br /></span><span style="color: rgb(0, 128, 128);"> 2</span> <span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">use</span><span style="color: rgb(0, 0, 0);"> strict;<br /></span><span style="color: rgb(0, 128, 128);"> 3</span> <span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">use</span><span style="color: rgb(0, 0, 0);"> Encode;<br /></span><span style="color: rgb(0, 128, 128);"> 4</span> <span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">use</span><span style="color: rgb(0, 0, 0);"> Net</span><span style="color: rgb(0, 0, 0);">::</span><span style="color: rgb(0, 0, 0);">FTP;<br /></span><span style="color: rgb(0, 128, 128);"> 5</span> <span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">use</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">Time</span><span style="color: rgb(0, 0, 0);">::</span><span style="color: rgb(0, 0, 255);">Local</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 128, 128);"> 6</span> <span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">use</span><span style="color: rgb(0, 0, 0);"> Tk;<br /></span><span style="color: rgb(0, 128, 128);"> 7</span> <span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">use</span><span style="color: rgb(0, 0, 0);"> Tk</span><span style="color: rgb(0, 0, 0);">::</span><span style="color: rgb(0, 0, 0);">BrowseEntry;<br /></span><span style="color: rgb(0, 128, 128);"> 8</span> <span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);"> 9</span> <span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">my</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$hw</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> Win32</span><span style="color: rgb(0, 0, 0);">::</span><span style="color: rgb(0, 0, 0);">GUI</span><span style="color: rgb(0, 0, 0);">::</span><span style="color: rgb(0, 0, 0);">GetPerlWindow();<br /></span><span style="color: rgb(0, 128, 128);">10</span> <span style="color: rgb(0, 0, 0);">Win32</span><span style="color: rgb(0, 0, 0);">::</span><span style="color: rgb(0, 0, 0);">GUI</span><span style="color: rgb(0, 0, 0);">::</span><span style="color: rgb(0, 0, 0);">Hide(</span><span style="color: rgb(128, 0, 128);">$hw</span><span style="color: rgb(0, 0, 0);">);<br /></span><span style="color: rgb(0, 128, 128);">11</span> <span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);">12</span> <span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">my</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(128, 0, 128);">$sec</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 128);">$min</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 128);">$hour</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 128);">$mday</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 128);">$mon</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 128);">$year</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 128);">$wday</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 128);">$yday</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 128);">$isdst</span><span style="color: rgb(0, 0, 0);">) </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">localtime</span><span style="color: rgb(0, 0, 0);">();<br /></span><span style="color: rgb(0, 128, 128);">13</span> <span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">my</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">@t</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">localtime</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">time</span><span style="color: rgb(0, 0, 0);">() </span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">86400</span><span style="color: rgb(0, 0, 0);">);<br /></span><span style="color: rgb(0, 128, 128);">14</span> <span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">my</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$tm</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 128, 128);">15</span> <span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">my</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$bt</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 128, 128);">16</span> <span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">my</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$mw</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 128, 128);">17</span> <span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">my</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$signal</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 128, 128);">18</span> <span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">my</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$sd</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">sprintf</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">%d</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$t</span><span style="color: rgb(0, 0, 0);">[</span><span style="color: rgb(128, 0, 0);">5</span><span style="color: rgb(0, 0, 0);">] </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">1900</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 255);">sprintf</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">%.2d</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$t</span><span style="color: rgb(0, 0, 0);">[</span><span style="color: rgb(128, 0, 0);">4</span><span style="color: rgb(0, 0, 0);">] </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 255);">sprintf</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">%.2d</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$t</span><span style="color: rgb(0, 0, 0);">[</span><span style="color: rgb(128, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">]);<br /></span><span style="color: rgb(0, 128, 128);">19</span> <span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">my</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$data</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">sprintf</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">%d</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$t</span><span style="color: rgb(0, 0, 0);">[</span><span style="color: rgb(128, 0, 0);">5</span><span style="color: rgb(0, 0, 0);">] </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">1900</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">-</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 255);">sprintf</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">%.2d</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$t</span><span style="color: rgb(0, 0, 0);">[</span><span style="color: rgb(128, 0, 0);">4</span><span style="color: rgb(0, 0, 0);">] </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">-</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 255);">sprintf</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">%.2d</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$t</span><span style="color: rgb(0, 0, 0);">[</span><span style="color: rgb(128, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">]);<br /></span><span style="color: rgb(0, 128, 128);">20</span> <span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">my</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$ta</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">sprintf</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">%d</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$year</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">1900</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">-</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 255);">sprintf</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">%.2d</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$mon</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">-</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 255);">sprintf</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">%.2d</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$mday</span><span style="color: rgb(0, 0, 0);">);<br /></span><span style="color: rgb(0, 128, 128);">21</span> <span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);">22</span> <span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">sub</span><span style="color: rgb(0, 0, 0);"> hanzi { </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> decode(</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">gb2312</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">shift</span><span style="color: rgb(0, 0, 0);">); }<br /></span><span style="color: rgb(0, 128, 128);">23</span> <span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">sub</span><span style="color: rgb(0, 0, 0);"> shezhi {<br /></span><span style="color: rgb(0, 128, 128);">24</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(128, 0, 128);">$tm</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> timelocal(</span><span style="color: rgb(128, 0, 128);">$sec</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 128);">$min</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 128);">$hour</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 128);">$mday</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 128);">$mon</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(128, 0, 128);">$year</span><span style="color: rgb(0, 0, 0);">);<br /></span><span style="color: rgb(0, 128, 128);">25</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(128, 0, 128);">$signal</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 128, 128);">26</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">open</span><span style="color: rgb(0, 0, 0);"> C</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">chonglu.rpjf</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 128, 128);">27</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">open</span><span style="color: rgb(0, 0, 0);"> T</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">&gt;temp</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 128, 128);">28</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">while</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">C</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">) { <br /></span><span style="color: rgb(0, 128, 128);">29</span> <span style="color: rgb(0, 0, 0);">        </span><span style="color: rgb(0, 0, 255);">chomp</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 128, 128);">30</span> <span style="color: rgb(0, 0, 0);">        </span><span style="color: rgb(128, 0, 128);">$_</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=~</span><span style="color: rgb(0, 0, 0);"> s</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">.*</span><span style="color: rgb(0, 0, 0);">)([</span><span style="color: rgb(128, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(128, 0, 0);">9</span><span style="color: rgb(0, 0, 0);">]{</span><span style="color: rgb(128, 0, 0);">8</span><span style="color: rgb(0, 0, 0);">})(</span><span style="color: rgb(0, 0, 0);">.*</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">$</span><span style="color: rgb(128, 0, 0);">1</span><span style="color: rgb(128, 0, 128);">$sd</span><span style="color: rgb(0, 0, 0);">$</span><span style="color: rgb(128, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 128, 128);">31</span> <span style="color: rgb(0, 0, 0);">        </span><span style="color: rgb(128, 0, 128);">$_</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=~</span><span style="color: rgb(0, 0, 0);"> s</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">.*</span><span style="color: rgb(0, 0, 0);">)([</span><span style="color: rgb(128, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(128, 0, 0);">9</span><span style="color: rgb(0, 0, 0);">]{</span><span style="color: rgb(128, 0, 0);">4</span><span style="color: rgb(0, 0, 0);">}</span><span style="color: rgb(0, 0, 0);">\-</span><span style="color: rgb(0, 0, 0);">[</span><span style="color: rgb(128, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(128, 0, 0);">9</span><span style="color: rgb(0, 0, 0);">]{</span><span style="color: rgb(128, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">}</span><span style="color: rgb(0, 0, 0);">\-</span><span style="color: rgb(0, 0, 0);">[</span><span style="color: rgb(128, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(128, 0, 0);">9</span><span style="color: rgb(0, 0, 0);">]{</span><span style="color: rgb(128, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">})(</span><span style="color: rgb(0, 0, 0);">.*</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">$</span><span style="color: rgb(128, 0, 0);">1</span><span style="color: rgb(128, 0, 128);">$data</span><span style="color: rgb(0, 0, 0);">$</span><span style="color: rgb(128, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 128, 128);">32</span> <span style="color: rgb(0, 0, 0);">        </span><span style="color: rgb(0, 0, 255);">print</span><span style="color: rgb(0, 0, 0);"> T </span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">$_\n</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 128, 128);">33</span> <span style="color: rgb(0, 0, 0);">    }<br /></span><span style="color: rgb(0, 128, 128);">34</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">close</span><span style="color: rgb(0, 0, 0);"> C; </span><span style="color: rgb(0, 0, 255);">close</span><span style="color: rgb(0, 0, 0);"> T;<br /></span><span style="color: rgb(0, 128, 128);">35</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">system</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">del chonglu.rpjf</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 128, 128);">36</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">system</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">rename temp chonglu.rpjf</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 128, 128);">37</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(128, 0, 128);">$bt</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">configure(</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">state </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">disable</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);">);<br /></span><span style="color: rgb(0, 128, 128);">38</span> <span style="color: rgb(0, 0, 0);">}<br /></span><span style="color: rgb(0, 128, 128);">39</span> <span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">sub</span><span style="color: rgb(0, 0, 0);"> monitor {<br /></span><span style="color: rgb(0, 128, 128);">40</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(128, 0, 128);">$signal</span><span style="color: rgb(0, 0, 0);">) { <br /></span><span style="color: rgb(0, 128, 128);">41</span> <span style="color: rgb(0, 0, 0);">        </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 255);">time</span><span style="color: rgb(0, 0, 0);">() </span><span style="color: rgb(0, 0, 0);">&gt;=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$tm</span><span style="color: rgb(0, 0, 0);">) {<br /></span><span style="color: rgb(0, 128, 128);">42</span> <span style="color: rgb(0, 0, 0);">            </span><span style="color: rgb(128, 0, 128);">$signal</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 128, 128);">43</span> <span style="color: rgb(0, 0, 0);">            </span><span style="color: rgb(0, 0, 255);">system</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">producer -j "d:\shixian\chonglu.rpjf" -daw -lc "e,i"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 128, 128);">44</span> <span style="color: rgb(0, 0, 0);">        }<br /></span><span style="color: rgb(0, 128, 128);">45</span> <span style="color: rgb(0, 0, 0);">        </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">e </span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">shixian$sd.rm</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">) {<br /></span><span style="color: rgb(0, 128, 128);">46</span> <span style="color: rgb(0, 0, 0);">            </span><span style="color: rgb(0, 0, 255);">my</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$f</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> Net</span><span style="color: rgb(0, 0, 0);">::</span><span style="color: rgb(0, 0, 0);">FTP</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">new(</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">media.zsgd.com</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);">) or </span><span style="color: rgb(0, 0, 255);">print</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">ftp failed</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 128, 128);">47</span> <span style="color: rgb(0, 0, 0);">            </span><span style="color: rgb(128, 0, 128);">$f</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">login(</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">jh</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">2020038</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);">);<br /></span><span style="color: rgb(0, 128, 128);">48</span> <span style="color: rgb(0, 0, 0);">            </span><span style="color: rgb(128, 0, 128);">$f</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">put(</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">shixian$sd.rm</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">);<br /></span><span style="color: rgb(0, 128, 128);">49</span> <span style="color: rgb(0, 0, 0);">            </span><span style="color: rgb(128, 0, 128);">$f</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">quit();<br /></span><span style="color: rgb(0, 128, 128);">50</span> <span style="color: rgb(0, 0, 0);">            </span><span style="color: rgb(0, 0, 255);">print</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0); font-weight: bold;">send complete\n</span><span style="color: rgb(0, 0, 0); font-weight: bold;">"</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 128, 128);">51</span> <span style="color: rgb(0, 0, 0);">        }<br /></span><span style="color: rgb(0, 128, 128);">52</span> <span style="color: rgb(0, 0, 0);">    }<br /></span><span style="color: rgb(0, 128, 128);">53</span> <span style="color: rgb(0, 0, 0);">}<br /></span><span style="color: rgb(0, 128, 128);">54</span> <span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 128);">55</span> <span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(128, 0, 128);">$mw</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> MainWindow</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">new(</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">title </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> hanzi(</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">视线重录</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);">));<br /></span><span style="color: rgb(0, 128, 128);">56</span> <span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(128, 0, 128);">$mw</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">Label(</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">text </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$ta</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 255);">pack</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">side </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">left</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">expand </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">fill </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">x</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);">);<br /></span><span style="color: rgb(0, 128, 128);">57</span> <span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);"> (([</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">小时</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">\</span><span style="color: rgb(128, 0, 128);">$hour</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> [</span><span style="color: rgb(128, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">..</span><span style="color: rgb(128, 0, 0);">23</span><span style="color: rgb(0, 0, 0);">]]</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> [</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">分</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">\</span><span style="color: rgb(128, 0, 128);">$min</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> [</span><span style="color: rgb(128, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">..</span><span style="color: rgb(128, 0, 0);">59</span><span style="color: rgb(0, 0, 0);">]]</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> [</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">秒</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">\</span><span style="color: rgb(128, 0, 128);">$sec</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> [</span><span style="color: rgb(128, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">..</span><span style="color: rgb(128, 0, 0);">59</span><span style="color: rgb(0, 0, 0);">]])) {<br /></span><span style="color: rgb(0, 128, 128);">58</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(128, 0, 128);">$mw</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">BrowseEntry(</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">label </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> hanzi(</span><span style="color: rgb(128, 0, 128);">$_</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">[</span><span style="color: rgb(128, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">])</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">variable </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$_</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">[</span><span style="color: rgb(128, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">]</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">choices </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$_</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">[</span><span style="color: rgb(128, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">])</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 255);">pack</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">side </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">left</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">expand </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">fill </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">x</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);">);<br /></span><span style="color: rgb(0, 128, 128);">59</span> <span style="color: rgb(0, 0, 0);">}<br /></span><span style="color: rgb(0, 128, 128);">60</span> <span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(128, 0, 128);">$bt</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">$mw</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">Button(</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">text </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> hanzi(</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">设置</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">command </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">\&amp;</span><span style="color: rgb(0, 0, 0);">shezhi)</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 255);">pack</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">side </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0); font-weight: bold;">bottom</span><span style="color: rgb(0, 0, 0); font-weight: bold;">'</span><span style="color: rgb(0, 0, 0);">);<br /></span><span style="color: rgb(0, 128, 128);">61</span> <span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(128, 0, 128);">$mw</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">resizable(</span><span style="color: rgb(128, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">);<br /></span><span style="color: rgb(0, 128, 128);">62</span> <span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(128, 0, 128);">$mw</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">repeat(</span><span style="color: rgb(128, 0, 0);">1000</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">\&amp;</span><span style="color: rgb(0, 0, 0);">monitor);<br /></span><span style="color: rgb(0, 128, 128);">63</span> <span style="color: rgb(0, 0, 0);">MainLoop();<br /></span><span style="color: rgb(0, 128, 128);">64</span> <span style="color: rgb(0, 0, 0);"></span></div><br /><img src ="http://www.cnitblog.com/gyn/aggbug/42051.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/gyn/" target="_blank">gyn_tadao</a> 2008-04-07 11:36 <a href="http://www.cnitblog.com/gyn/archive/2008/04/07/42051.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>检索mp3的脚本</title><link>http://www.cnitblog.com/gyn/archive/2008/04/05/41993.html</link><dc:creator>gyn_tadao</dc:creator><author>gyn_tadao</author><pubDate>Sat, 05 Apr 2008 08:57:00 GMT</pubDate><guid>http://www.cnitblog.com/gyn/archive/2008/04/05/41993.html</guid><wfw:comment>http://www.cnitblog.com/gyn/comments/41993.html</wfw:comment><comments>http://www.cnitblog.com/gyn/archive/2008/04/05/41993.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/gyn/comments/commentRss/41993.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/gyn/services/trackbacks/41993.html</trackback:ping><description><![CDATA[播出软件的音频解码单元无法处理一些特殊码率的mp3文件，为了保证播放的安全和流畅，需要将这些特殊码率的文件剔除掉。使用诸如千千静听和foobar等播放器都可以查看文件的码率，但是如果文件数量很多，这种人工查看的办法非常费时。所以用脚本来完成一项工作。<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008080"> 1</span><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #0000ff">use</span><span style="COLOR: #000000"> strict;<br /></span><span style="COLOR: #008080"> 2</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">use</span><span style="COLOR: #000000"> File</span><span style="COLOR: #000000">::</span><span style="COLOR: #000000">Find;<br /></span><span style="COLOR: #008080"> 3</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">use</span><span style="COLOR: #000000"> MP3</span><span style="COLOR: #000000">::</span><span style="COLOR: #000000">Tag;<br /></span><span style="COLOR: #008080"> 4</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><br /></span><span style="COLOR: #008080"> 5</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">my</span><span style="COLOR: #000000"> (</span><span style="COLOR: #800080">$path</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000"> </span><span style="COLOR: #800080">$delete</span><span style="COLOR: #000000">) </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #800080">@ARGV</span><span style="COLOR: #000000">;<br /></span><span style="COLOR: #008080"> 6</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><br /></span><span style="COLOR: #008080"> 7</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />find(</span><span style="COLOR: #000000">\&amp;</span><span style="COLOR: #000000">wanted</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000"> </span><span style="COLOR: #800080">$path</span><span style="COLOR: #000000">);<br /></span><span style="COLOR: #008080"> 8</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><br /></span><span style="COLOR: #008080"> 9</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">sub</span><span style="COLOR: #000000"> wanted{<br /></span><span style="COLOR: #008080">10</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #000000">/\.</span><span style="COLOR: #000000">mp3$</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">do</span><span style="COLOR: #000000"> {<br /></span><span style="COLOR: #008080">11</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff">my</span><span style="COLOR: #000000"> </span><span style="COLOR: #800080">$mp3</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> MP3</span><span style="COLOR: #000000">::</span><span style="COLOR: #000000">Tag</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">new(</span><span style="FONT-WEIGHT: bold; COLOR: #000000">"</span><span style="FONT-WEIGHT: bold; COLOR: #000000">$_</span><span style="FONT-WEIGHT: bold; COLOR: #000000">"</span><span style="COLOR: #000000">);<br /></span><span style="COLOR: #008080">12</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (</span><span style="COLOR: #0000ff">defined</span><span style="COLOR: #000000">(</span><span style="COLOR: #800080">$mp3</span><span style="COLOR: #000000">) </span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000"> is_normal_bitrate(</span><span style="COLOR: #800080">$mp3</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">bitrate_kbps())){<br /></span><span style="COLOR: #008080">13</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />            remove(</span><span style="COLOR: #800080">$_</span><span style="COLOR: #000000">);<br /></span><span style="COLOR: #008080">14</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />        }<br /></span><span style="COLOR: #008080">15</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    };<br /></span><span style="COLOR: #008080">16</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />}<br /></span><span style="COLOR: #008080">17</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><br /></span><span style="COLOR: #008080">18</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">sub</span><span style="COLOR: #000000"> is_normal_bitrate{<br /></span><span style="COLOR: #008080">19</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">my</span><span style="COLOR: #000000"> </span><span style="COLOR: #800080">$bitrate</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">shift</span><span style="COLOR: #000000">;<br /></span><span style="COLOR: #008080">20</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> (</span><span style="COLOR: #800000">64</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000"> </span><span style="COLOR: #800000">128</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000"> </span><span style="COLOR: #800000">192</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000"> </span><span style="COLOR: #800000">256</span><span style="COLOR: #000000">){<br /></span><span style="COLOR: #008080">21</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(</span><span style="COLOR: #800080">$bitrate</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #800080">$_</span><span style="COLOR: #000000">) {<br /></span><span style="COLOR: #008080">22</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />            </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #800000">1</span><span style="COLOR: #000000">;<br /></span><span style="COLOR: #008080">23</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />        }<br /></span><span style="COLOR: #008080">24</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    }<br /></span><span style="COLOR: #008080">25</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #800000">0</span><span style="COLOR: #000000">;<br /></span><span style="COLOR: #008080">26</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />}<br /></span><span style="COLOR: #008080">27</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><br /></span><span style="COLOR: #008080">28</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">sub</span><span style="COLOR: #000000"> remove{<br /></span><span style="COLOR: #008080">29</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">my</span><span style="COLOR: #000000"> </span><span style="COLOR: #800080">$filename</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">shift</span><span style="COLOR: #000000">;<br /></span><span style="COLOR: #008080">30</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">my</span><span style="COLOR: #000000"> </span><span style="COLOR: #800080">@paths</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">split</span><span style="COLOR: #000000">(</span><span style="COLOR: #000000">/\//,</span><span style="COLOR: #000000"> </span><span style="COLOR: #800080">$path</span><span style="COLOR: #000000">);<br /></span><span style="COLOR: #008080">31</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">my</span><span style="COLOR: #000000"> </span><span style="COLOR: #800080">$recycled</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #800080">$paths</span><span style="COLOR: #000000">[</span><span style="COLOR: #800000">0</span><span style="COLOR: #000000">]</span><span style="COLOR: #000000">.</span><span style="FONT-WEIGHT: bold; COLOR: #000000">"</span><span style="FONT-WEIGHT: bold; COLOR: #000000">/$filename</span><span style="FONT-WEIGHT: bold; COLOR: #000000">"</span><span style="COLOR: #000000">;<br /></span><span style="COLOR: #008080">32</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    <br /></span><span style="COLOR: #008080">33</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">open</span><span style="COLOR: #000000">(FILE</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000"> </span><span style="COLOR: #800080">$filename</span><span style="COLOR: #000000">);<br /></span><span style="COLOR: #008080">34</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">open</span><span style="COLOR: #000000">(ANO</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000"> </span><span style="FONT-WEIGHT: bold; COLOR: #000000">"</span><span style="FONT-WEIGHT: bold; COLOR: #000000">&gt;</span><span style="FONT-WEIGHT: bold; COLOR: #000000">"</span><span style="COLOR: #000000">.</span><span style="COLOR: #800080">$recycled</span><span style="COLOR: #000000">) or </span><span style="COLOR: #0000ff">die</span><span style="COLOR: #000000"> $</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">;<br /></span><span style="COLOR: #008080">35</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    <br /></span><span style="COLOR: #008080">36</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">binmode</span><span style="COLOR: #000000"> FILE;<br /></span><span style="COLOR: #008080">37</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">binmode</span><span style="COLOR: #000000"> ANO;<br /></span><span style="COLOR: #008080">38</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    <br /></span><span style="COLOR: #008080">39</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">my</span><span style="COLOR: #000000"> </span><span style="COLOR: #800080">$offset</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #800000">0</span><span style="COLOR: #000000">;<br /></span><span style="COLOR: #008080">40</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">my</span><span style="COLOR: #000000"> </span><span style="COLOR: #800080">$buffer</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">undef</span><span style="COLOR: #000000">;<br /></span><span style="COLOR: #008080">41</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">my</span><span style="COLOR: #000000"> </span><span style="COLOR: #800080">$number</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #800000">0</span><span style="COLOR: #000000">;<br /></span><span style="COLOR: #008080">42</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">((</span><span style="COLOR: #800080">$number</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">sysread</span><span style="COLOR: #000000">(FILE</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000"> </span><span style="COLOR: #800080">$buffer</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000"> </span><span style="COLOR: #800000">1024</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000"> </span><span style="COLOR: #800080">$offset</span><span style="COLOR: #000000">)) </span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000"> </span><span style="COLOR: #800000">0</span><span style="COLOR: #000000">){<br /></span><span style="COLOR: #008080">43</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff">syswrite</span><span style="COLOR: #000000">(ANO</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000"> </span><span style="COLOR: #800080">$buffer</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000"> </span><span style="COLOR: #800080">$number</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000"> </span><span style="COLOR: #800080">$offset</span><span style="COLOR: #000000">);<br /></span><span style="COLOR: #008080">44</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #800080">$offset</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">+=</span><span style="COLOR: #000000"> </span><span style="COLOR: #800080">$number</span><span style="COLOR: #000000">;<br /></span><span style="COLOR: #008080">45</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    }<br /></span><span style="COLOR: #008080">46</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    <br /></span><span style="COLOR: #008080">47</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">close</span><span style="COLOR: #000000"> FILE;<br /></span><span style="COLOR: #008080">48</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">close</span><span style="COLOR: #000000"> ANO;<br /></span><span style="COLOR: #008080">49</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    <br /></span><span style="COLOR: #008080">50</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(</span><span style="COLOR: #800080">$delete</span><span style="COLOR: #000000"> eq </span><span style="FONT-WEIGHT: bold; COLOR: #000000">"</span><span style="FONT-WEIGHT: bold; COLOR: #000000">-d</span><span style="FONT-WEIGHT: bold; COLOR: #000000">"</span><span style="COLOR: #000000">) {</span><span style="COLOR: #0000ff">unlink</span><span style="COLOR: #000000"> </span><span style="COLOR: #800080">$_</span><span style="COLOR: #000000">;}<br /></span><span style="COLOR: #008080">51</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />}</span></div><img src ="http://www.cnitblog.com/gyn/aggbug/41993.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/gyn/" target="_blank">gyn_tadao</a> 2008-04-05 16:57 <a href="http://www.cnitblog.com/gyn/archive/2008/04/05/41993.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>基于串口心跳的双机热备Perl代码(下载)</title><link>http://www.cnitblog.com/gyn/archive/2007/11/29/37031.html</link><dc:creator>gyn_tadao</dc:creator><author>gyn_tadao</author><pubDate>Thu, 29 Nov 2007 06:07:00 GMT</pubDate><guid>http://www.cnitblog.com/gyn/archive/2007/11/29/37031.html</guid><wfw:comment>http://www.cnitblog.com/gyn/comments/37031.html</wfw:comment><comments>http://www.cnitblog.com/gyn/archive/2007/11/29/37031.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/gyn/comments/commentRss/37031.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/gyn/services/trackbacks/37031.html</trackback:ping><description><![CDATA[
		<p>(下载<a title="serial_heartbeat.rxr" href="/Files/gyn/serial_heartbeat.rar">serial_heartbeat.rar</a>)压缩包里有两个文件夹，一个用于主机，一个用于备机。串口参数修改在serial.conf中；检测参数在parameters.txt中一般不需要修改；网卡参数设置在inetrface开头的文件中，其中interface_null不需要修改。运行时，请确保已安装了perl 和Win32::SerialPort模块。由于上载空间有限，不提供exe文件下载。有需要可电邮我<a href="mailto:jh@zsgd.com">jh@zsgd.com</a>。</p>
<img src ="http://www.cnitblog.com/gyn/aggbug/37031.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/gyn/" target="_blank">gyn_tadao</a> 2007-11-29 14:07 <a href="http://www.cnitblog.com/gyn/archive/2007/11/29/37031.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>perl串口通信实例</title><link>http://www.cnitblog.com/gyn/archive/2007/11/27/36919.html</link><dc:creator>gyn_tadao</dc:creator><author>gyn_tadao</author><pubDate>Tue, 27 Nov 2007 06:40:00 GMT</pubDate><guid>http://www.cnitblog.com/gyn/archive/2007/11/27/36919.html</guid><wfw:comment>http://www.cnitblog.com/gyn/comments/36919.html</wfw:comment><comments>http://www.cnitblog.com/gyn/archive/2007/11/27/36919.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/gyn/comments/commentRss/36919.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/gyn/services/trackbacks/36919.html</trackback:ping><description><![CDATA[
		<p>
				<font face="Arial">使用串口通信，在备机端使用如下脚本检测来自主机的心跳信号，一旦未接受次数超过指定记数，备机认为主机DOWN机，自动设置为主机的网络参数，顶替主机提供服务。</font>
		</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />
				<span style="COLOR: #008000">#</span>
				<span style="COLOR: #008000">! perl -w</span>
				<span style="COLOR: #008000">
						<br />
						<img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />
				</span>
				<span style="COLOR: #000000">
						<br />
						<img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />
				</span>
				<span style="COLOR: #0000ff">use</span>
				<span style="COLOR: #000000"> strict;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /></span>
				<span style="COLOR: #0000ff">use</span>
				<span style="COLOR: #000000"> Win32</span>
				<span style="COLOR: #000000">::</span>
				<span style="COLOR: #000000">SerialPort;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /></span>
				<span style="COLOR: #0000ff">my</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #800080">$port</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> </span>
				<span style="FONT-WEIGHT: bold; COLOR: #000000">'</span>
				<span style="FONT-WEIGHT: bold; COLOR: #000000">COM2</span>
				<span style="FONT-WEIGHT: bold; COLOR: #000000">'</span>
				<span style="COLOR: #000000">; </span>
				<span style="COLOR: #008000">#</span>
				<span style="COLOR: #008000"> serail port name registried in OS</span>
				<span style="COLOR: #008000">
						<br />
						<img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />
				</span>
				<span style="COLOR: #0000ff">my</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #800080">$count</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #800000">0</span>
				<span style="COLOR: #000000">; </span>
				<span style="COLOR: #008000">#</span>
				<span style="COLOR: #008000"> count number of heartbeat-receiving failture</span>
				<span style="COLOR: #008000">
						<br />
						<img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />
				</span>
				<span style="COLOR: #0000ff">my</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #800080">$max_count</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #800000">5</span>
				<span style="COLOR: #000000">; </span>
				<span style="COLOR: #008000">#</span>
				<span style="COLOR: #008000"> max fail count to be tolerated </span>
				<span style="COLOR: #008000">
						<br />
						<img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />
				</span>
				<span style="COLOR: #0000ff">my</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #800080">$interface</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> </span>
				<span style="FONT-WEIGHT: bold; COLOR: #000000">'</span>
				<span style="FONT-WEIGHT: bold; COLOR: #000000">
						<br />
						<img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />
						<br />
						<img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /># ---------------------------------- <br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /># 接口 IP 配置         <br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /># ---------------------------------- <br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />pushd interface ip<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /># "local" 的接口 IP  配置<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />set address name="local" source=static addr=192.168.6.185 mask=255.255.255.0<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />set address name="local" gateway=192.168.6.65 gwmetric=0<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />set dns name="local" source=static addr=192.168.6.112 register=PRIMARY<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />add dns name="local" addr=192.168.6.201 index=2<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />set wins name="local" source=static addr=none<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />popd<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /># 接口 IP 配置结束<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /></span>
				<span style="FONT-WEIGHT: bold; COLOR: #000000">'</span>
				<span style="COLOR: #000000">; </span>
				<span style="COLOR: #008000">#</span>
				<span style="COLOR: #008000"> net inetrface config information</span>
				<span style="COLOR: #008000">
						<br />
						<img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />
				</span>
				<span style="COLOR: #000000">
						<br />
						<img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />
				</span>
				<span style="COLOR: #0000ff">sub</span>
				<span style="COLOR: #000000"> errlog {<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    </span>
				<span style="COLOR: #008000">#</span>
				<span style="COLOR: #008000">log the failtrue occuring time</span>
				<span style="COLOR: #008000">
						<br />
						<img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />
				</span>
				<span style="COLOR: #000000">    <br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    </span>
				<span style="COLOR: #0000ff">open</span>
				<span style="COLOR: #000000"> ERR</span>
				<span style="COLOR: #000000">,</span>
				<span style="COLOR: #000000"> </span>
				<span style="FONT-WEIGHT: bold; COLOR: #000000">'</span>
				<span style="FONT-WEIGHT: bold; COLOR: #000000">&gt;&gt;err.log</span>
				<span style="FONT-WEIGHT: bold; COLOR: #000000">'</span>
				<span style="COLOR: #000000">;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    </span>
				<span style="COLOR: #0000ff">my</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #800080">@time</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">localtime</span>
				<span style="COLOR: #000000">();<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />    </span>
				<span style="COLOR: #0000ff">my</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #800080">$time</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #0000ff">sprintf</span>
				<span style="COLOR: #000000">(</span>
				<span style="FONT-WEIGHT: bold; COLOR