【问题标题】:Perl TCP, print, select, and sysread - buffering behaviorPerl TCP、打印、选择和 sysread - 缓冲行为
【发布时间】:2013-01-13 21:43:44
【问题描述】:

客户:

$socket->autoflush(1);
print $socket "abel\n";
print $socket "baker\n";
print $socket "charlie\n";

我的问题:

当服务器的select()(或can_read)完成时,我对系统receive缓冲区的内容有什么保证?它是否可以包含一个“a”?还是“abel\nbak”?或者系统缓冲区是否保证恰好包含从客户端中相应的“打印”语句发送的字符串中的一个、两个或全部三个?

这显然对我如何管理应用程序级缓冲区有影响。

【问题讨论】:

    标签: perl tcp buffer


    【解决方案1】:

    TCP(和一般的 SOCK_STREAM)没有这样的保证。您列出的任何内容都是可能的。

    【讨论】:

    • 我也很怀疑。是否偶然有一个 Perl 模块在更高级别上实现了 select(),表明可以在不阻塞的情况下检索完整的行尾终止字符串?还是我必须自己管理?
    • 我不知道 Perl,但是例如在 TCL 中,我们将套接字置于非阻塞模式并使用普通的gets(即高级读行函数)。如果该行不完整,它只返回“nothing”(带有一个标志),但部分行保持缓冲。所以当“gets”失败时,我们只需要再次“select”。 Perl 必须有等价的东西。
    • 我几乎肯定它确实如此;我只是不知道它是干什么用的。谢谢 - 你已经回答了我的问题。
    【解决方案2】:

    没有任何保证。 "a" 和 "abel\nbak" 都是可能的。

    如果有可用数据,sysread 不会阻塞;它将返回可用的内容。因此,您可以使用

    for my $fh (@ready) {
       my $close = 0;
       my $client = $clients{$fh};
    
       our $buf; local *buf = $client->{buf};
       my $rv = sysread($buf, 0, 64*1024, length($buf)); 
       if ($rv) {
          while ($buf =~ s/^(.*)\n//) {
             my $msg = $1;
             $close = 1 if process_msg($msg);
          }
       } else {
          $close = 1;
          # Handle error and eof here.
       }
    
       if ($close) {
          $readers->delete($fh);
          delete $clients->{$fh};
       }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-13
      • 2014-06-23
      • 2019-07-05
      • 2015-07-27
      • 1970-01-01
      • 2012-03-17
      • 2014-05-30
      • 1970-01-01
      相关资源
      最近更新 更多