PHP流写缓冲区

Col*_*n M 2 php sockets php-socket

我试图以非阻塞方式向流中写入大量数据(~250K).

抽象出复杂性和对象结构,这就是我正在运行的:

$fp = fsockopen('host', 80);
socket_set_blocking( $fp, false );
fwrite( $fp, $string, $length ); // Where $string is a 250K string
Run Code Online (Sandbox Code Playgroud)

但是,数据并非都写入.假设这是PHP的写缓冲区,我设置stream_set_write_buffer( $fp, 0 )但是也没有解决问题.

我把我的fwrite打成了4096B的块 - 看起来客户端发送了3个完整的批次(4096字节)和第四批的~1500B.对fwrite的任何和所有连续调用都返回0字节写入.

有没有人知道如何将这些数据排队以非阻塞的方式发送出去?如果我删除socket_set_blocking( $fp, false );- 一切正常.很明显,这是异步运行它的问题.

你的想法是什么?套接字扩展是否会对此有所帮助?它以不同方式处理缓冲区吗

注意:我故意编写此套接字传输层以避免因各种原因使用curl.使用curl_multi()不是一种选择.

rdl*_*rey 5

您的问题几乎可以肯定是由于fwrite新数据包到达可能会中断非阻塞套接字流上的操作.因此,你不能指望一个fwrite原子.在这种情况下,您必须依赖fwrite调用的返回值来确切地告诉您在该过程中向该流写入了多少字节并继续写入,直到您的所有数据都被发送.

例如 ...

$dataToWrite = 'my data';
$bytesToWrite = strlen($dataToWrite);
$totalBytesWritten = 0;

while ($totalBytesWritten < $bytesToWrite) {
    $bytes = fwrite($mySock, substr($dataToWrite, $totalBytesWritten));
    $totalBytesWritten += $bytes;
}
Run Code Online (Sandbox Code Playgroud)

显然,对此问题的可靠处理还必须考虑插座连接消失的情况等.