PHP socket_read() 只获取流的第一个字节

2024-01-02

在 Linux 中使用 socket_read() 时,我遇到了非常奇怪的行为。

我使用的 socket_read 的缓冲区限制为 2048。

在我的 Windows 系统上,它会获取整个响应,而在我的 Linux 服务器上,它只会获取响应的第一个字节。

$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if (!socket_connect($sock, 'my-server.dyndns.org', 8888)) {
   die('no connect');
}

$req = 'request';
socket_write($sock, $req);

if (false !== ($buf = socket_read($sock, 2048)) {
    echo $buf; // This only contains the first byte of the response.
}

socket_close($sock);

如果我再次调用 socket_read() 它会获取字符串的其余部分:

// This works: 

while((false !== ($buf = socket_read($sock, 2048)))) {
    echo "Read ".strlen($buf)." bytes from socket_read().\n";
    if ($buf == "") break;
    $b .= $buf;
    sleep(1);
}

/* Output: 
 *
 * Read 1 bytes from socket_read().
 * Read 307 bytes from socket_read().
 * Read 0 bytes from socket_read().
 * Done.
 */ 

如果我在调用 socket_read() 之前等待 2 秒,我也会得到有效的响应:

// This also works:

sleep(2);
if (false !== ($buf = socket_read($sock, 2048)) {
    echo $buf; // all 308 bytes are read correctly.
}

socket_read() 不应该等待缓冲区变满或字符串结尾吗?

我究竟做错了什么?


众所周知,Linux 上的网络堆栈比 Windows 上的网络堆栈更好(更快)(这是主观的,我们只是说:它的行为不同)。另一方面,这意味着您的代码也需要处理差异。

套接字不是实时的而是异步的。因此,如果您向套接字写入内容,则不能指望您已经可以在其上读取内容。您需要给远程守护进程一些时间来实际响应您的写入。

仅当远程端确实向您的套接字写入了某些内容并且网络已传输该数据时,您才可以读取它。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PHP socket_read() 只获取流的第一个字节 的相关文章

随机推荐