1

我是 Perl 的新手,并试图在 Link中理解这段代码: http ://codepaste.ru/1374/但我在理解这部分代码时遇到了一些问题:

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);
4

1 回答 1

1

基本上,select运算符用于查找哪些文件描述符已准备好(可读、可写或存在错误条件)。它将等到文件描述符之一准备好或超时。

select RBITS, WBITS, EBITS, TIMEOUT

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

vec EXPR, OFFSET, BITS

vec函数提供无符号整数列表的存储。EXPR是一个位字符串,OFFSET是位 in 的偏移量EXPR,并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将返回。或者如果没有人准备好,它将在 120 秒后返回。

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

于 2013-09-23T09:05:17.023 回答