2013-09-23 45 views
1

我在Perl新的,并试图了解这个鳕链接:http://codepaste.ru/1374/but我理解这部分代码的一些问题:袜子5代理Perl的

while($client || $target) { 
    my $rin = ""; 
    vec($rin, fileno($client), 1) = 1 if $client; 
    vec($rin, fileno($target), 1) = 1 if $target; 
    my($rout, $eout); 
    select($rout = $rin, undef, $eout = $rin, 120); 
    if (!$rout && !$eout) { return; } 
    my $cbuffer = ""; 
    my $tbuffer = ""; 

    if ($client && (vec($eout, fileno($client), 1) || vec($rout, fileno($client), 1))) { 
    my $result = sysread($client, $tbuffer, 1024); 
    if (!defined($result) || !$result) { return; } 
    } 

    if ($target && (vec($eout, fileno($target), 1) || vec($rout, fileno($target), 1))) { 
    my $result = sysread($target, $cbuffer, 1024); 
    if (!defined($result) || !$result) { return; } 
    } 

    if ($fh && $tbuffer) { print $fh $tbuffer; } 

    while (my $len = length($tbuffer)) { 
    my $res = syswrite($target, $tbuffer, $len); 
    if ($res > 0) { $tbuffer = substr($tbuffer, $res); } else { return; } 
    } 

    while (my $len = length($cbuffer)) { 
    my $res = syswrite($client, $cbuffer, $len); 
    if ($res > 0) { $cbuffer = substr($cbuffer, $res); } else { return; } 
    } 
} 

任何机构可以解释我到底什么发生在这些行:

vec($rin, fileno($client), 1) = 1 if $client; 
vec($rin, fileno($target), 1) = 1 if $target; 

select($rout = $rin, undef, $eout = $rin, 120); 

回答

1

基本上,selectÒ perator用于查找哪些文件描述符已准备好(可读,可写或有错误情况)。它将等待,直到其中一个文件描述符准备就绪或超时。

select RBITS, WBITS, EBITS, TIMEOUT 

RBITS是一个位掩码,通常保存为一个字符串,表示一组文件描述符select将等待可读性。 RBITS的每一位代表一个文件描述符,并且该位掩码中文件描述符的偏移量应该是系统中的文件描述符编号。因此,您可以使用vec来生成此位掩码。

vec EXPR, OFFSET, BITS 

vec函数提供存储无符号整数列表。 EXPR是一个位串,OFFSETEXPR中位的偏移量,BITS指定了您正在读取/写入到EXPR的每个元素的宽度。

所以这两条线:

vec($rin, fileno($client), 1) = 1; 
vec($rin, fileno($target), 1) = 1; 

他们提出了一个位掩码串$rin与设置,其偏移等于$client文件描述符号位,还有的$target之一。

把它放进select操作:

select($rout = $rin, undef, $eout = $rin, 120); 

然后select将监控两个文件处理程序($client$target)的可读性,如果其中一人已准备就绪,select将返回。或者如果没有人准备好,它会在120s后返回。

WBITS,EBITS使用相同的方法。所以你可以推断,当两个文件处理程序有任何异常时,上面的select行也会返回。