2
<?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($socket, '127.0.0.1', 100);
socket_listen($socket);
$client = socket_accept($socket);
socket_write($client, 'output');
sleep(10);
socket_close($client);
socket_close($socket);
?>

当我去终端并输入时,nc localhost 100我会立即得到输出,如我所愿。
但是当我localhost:100在浏览器的地址栏中输入“ ”时,10秒后会显示单词输出。

但!
如果我将代码更改为:

<?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($socket, '127.0.0.1', 100);
socket_listen($socket);
$client = socket_accept($socket);
$str = '';
for ($index = 0; $index < 4096; $index++) {
    $str .= ' ';
}
socket_write($client, $str);
socket_write($client, 'output');
sleep(10);
socket_close($client);
socket_close($socket);
?>

发送请求后,我立即在浏览器上获得输出(以及之前的所有空格)。

如何在不发送大量数据的情况下立即在浏览器中获取输出?

4

2 回答 2

2

您可能会看到这种行为,因为在第一种情况下,您发送的数据太小,因此输出缓冲区可能会一直保留它,直到填充足够的数据或关闭连接。

尝试在每次写入后使用ob_implicit_flush()或显式调用刷新数据:ob_flush()

<?php
ob_implicit_flush();
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($socket, '127.0.0.1', 100);
socket_listen($socket);
$client = socket_accept($socket);
socket_write($client, 'output');
sleep(10);
socket_close($client);
socket_close($socket);
?>
于 2012-08-22T09:07:39.030 回答
1
  1. 有可能启用的 PHP 的输出缓冲。按照 Samyam A 的描述刷新缓冲区。或者使用以下命令禁用它: using ob_end_flush();

  2. 浏览器本身可能会忽略数据,直到超过某个限制 (~1KB) 或连接已关闭。这是由于一些优化。他们假设文档的前 1KB 没有足够的有用信息来呈现文档的预览。解决方案:在开始时发送 1KB 的虚拟数据(例如空格)。然后正常发送数据。

  3. 可能有病毒扫描程序或工具栏充当代理服务器,它以首先获取完整数据块(甚至整个文档)的方式处理 HTTP 流,然后在完成后处理并转发该块. 如果您在端口 100 上工作,则不应发生这种情况(这是防止此类工具延迟数据流的常用技巧)。更多的是你在 localhost 工作。如果您之间确实有互联网提供商(尤其是移动网络运营商),您的数据可能会通过透明代理服务器传输,这也会导致此类问题。

于 2012-08-22T09:34:08.690 回答