首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >自动刷新在socket中做什么?我们为什么要使用它?

自动刷新在socket中做什么?我们为什么要使用它?
EN

Stack Overflow用户
提问于 2013-02-22 20:10:44
回答 3查看 7.9K关注 0票数 5

我正在编写一些套接字代码,无法弄清楚为什么在套接字上使用autoflush。大概是这样的

代码语言:javascript
复制
my $sock = IO::Socket::Unix(Peer => $socketfilename , Type => SOCK_STREAM)

autoflush $sock 1;

也有一些地方有

代码语言:javascript
复制
autoflush STDERR 1

autoflush STDOUT 1

用于通用文件处理程序。

是干什么的呢?另外,如果我不使用它,会发生什么?请给出一些实际的例子,这样我就会理解而不是简单的定义。

EN

回答 3

Stack Overflow用户

发布于 2013-02-22 20:14:18

数据通常不会立即在套接字上发送,它被缓冲到某个点,然后一次性发送。

自动刷新意味着数据直接通过缓冲区,然后刷新出去,而不是保留在缓冲区中等待其他数据到达和累积。

就这么简单。

如果没有自动刷新:

代码语言:javascript
复制
Tick | DATA sent|Socket Buffer| DATA received
.....|..........|.............|..............
1    | XX       | XX          | (nothing)
2    | yy       | yyXX        | (nothing)
3    | ZZZ      | ZZZyyXX     | (nothing)
4    | t        | (empty)     | tZZZyyXX

使用自动刷新功能:

代码语言:javascript
复制
Tick | DATA sent | Socket Buffer | DATA received
.....|...........|...............|..............
1    | XX        | ()            | XX
2    | yy        | ()            | yy
3    | ZZZ       | ()            | ZZZ
4    | t         | ()            | t

  • Socket Buffer size: 8 chars
  • 非常简单的例子,看过之后你可能会提出一些其他的问题--其中很大一部分也是依赖于实现的。此外,缓冲可以发生在不同的级别(发送方、接收方、应用程序等)。)
票数 9
EN

Stack Overflow用户

发布于 2013-02-22 20:31:50

它完全不做任何事情,...because IO::Socket::Unix已经为你做过了。

以块的形式发送数据的开销较小,因此文件库会将要打印的数据累积到缓冲区中,而不是立即发送到系统。仅当累积了4KB或8KB (取决于版本)的数据时,才会将数据实际发送到系统。这被称为“缓冲”。

将句柄的autoflush设置为true将禁用该句柄的缓冲。当您调用print时,数据会在print返回之前发送到系统。

看到不同点:

代码语言:javascript
复制
$ perl -e'
   STDOUT->autoflush($ARGV[0]);
   for (0..9) { print $_ x 1024; sleep 1; }
' 1
<whole bunch of 1s>
<one second later: whole bunch of 2s>
<one second later: whole bunch of 3s>
<one second later: whole bunch of 4s>
<one second later: whole bunch of 5s>
<one second later: whole bunch of 6s>
<one second later: whole bunch of 7s>
<one second later: whole bunch of 8s>
<one second later: whole bunch of 9s>

$ perl -e'
   STDOUT->autoflush($ARGV[0]);
   for (0..9) { print $_ x 1024; sleep 1; }
' 0
# Before Perl 5.14:
<four seconds later: whole bunch of 0s, 1s, 2s and 3s>
<four seconds later: whole bunch of 4s, 5s, 6s and 7s>
<two seconds later: whole bunch of 8s and 9s>
# Perl 5.14+
<eight seconds later: whole bunch of 0s, 1s, 2s, 3s, 4s, 5s, 6s and 7s>
<two seconds later: whole bunch of 8s and 9s>

autoflush是由IO::Socket::*打开的,因为大多数时候套接字都需要它。套接字通常用于交互式通信。请求、回复、请求、回复等等。想象一下,如果请求被困在缓冲区中会发生什么……你会永远等着回复的!

票数 7
EN

Stack Overflow用户

发布于 2013-02-23 20:20:56

来自IO::Handle

代码语言:javascript
复制
sub autoflush {
    my $old = new SelectSaver qualify($_[0], caller);
    my $prev = $|;
    $| = @_ > 1 ? $_[1] : 1;
    $prev;
}

没有魔法。

from

$|

如果设置为非零,则在当前选定的输出通道上执行每次写入或打印后立即强制刷新。缺省值为0(无论通道是否真正由系统缓冲;$|只会告诉您是否在每次写入后显式地要求Perl刷新)。如果输出到终端,STDOUT通常是行缓冲的,否则是块缓冲的。设置这个变量主要在输出到管道或套接字时很有用,比如在rsh下运行Perl程序,并希望看到正在发生的输出。这对输入缓冲没有影响。请参阅getc了解这一点。有关如何选择输出通道的信息,请参见select。另请参阅IO::Handle

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15023957

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档