Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
远程服务器关闭的套接字的PHP first fwrite()不会引发错误_Php_Sockets_Fwrite - Fatal编程技术网

远程服务器关闭的套接字的PHP first fwrite()不会引发错误

远程服务器关闭的套接字的PHP first fwrite()不会引发错误,php,sockets,fwrite,Php,Sockets,Fwrite,PHP版本:Debian 3.2.54-2 x86_64上的5.4.4。我正在使用流套接字。 我创建了简单的服务器和客户端应用程序来说明我的问题: <?php $client = false; $server_sock = stream_socket_server("tcp://127.0.0.1:20015", $errNo, $errorMessage); if ($server_sock == false) die("Could not bind to socket: {$errNo

PHP版本:Debian 3.2.54-2 x86_64上的5.4.4。我正在使用流套接字。 我创建了简单的服务器和客户端应用程序来说明我的问题:

<?php
$client = false;
$server_sock = stream_socket_server("tcp://127.0.0.1:20015", $errNo, $errorMessage);
if ($server_sock == false) die("Could not bind to socket: {$errNo} - {$errorMessage}"); 
while (true) { 
    if ($client !== false) {
        if (feof($client)) $data = false;
        else $data = stream_get_contents($client);
        if ($data === false) {
            fclose($client);
            $client = false;
            echo "Client disconnected\n";
            continue;
        } else if ($data === "") continue;
        echo "Received: " . $data . "\n";            
    } else {
        $clients = array($server_sock);
        $num_streams = stream_select($clients, $write = null, $except = null, 0, 200000);
        if ($num_streams > 0) {
            if (in_array($server_sock, $clients)) {
                $client = stream_socket_accept($server_sock);
                if ($client) {
                    if(!stream_set_blocking($client, 0)) echo "stream_set_blocking() error\n";
                } else {
                    echo "stream_socket_accept() error\n";
                    $client = false;
                }
            }
        }
    }
}
?>

客户端代码:

<?php
    $client = stream_socket_client("tcp://127.0.0.1:20015", $errNo, $errorMessage);
    if ($client == false) die("Could not connect to server: {$errNo} - {$errorMessage}\n");
    if(!stream_set_blocking($client, 0)) echo "stream_set_blocking() error\n";

    $tick = true;

    while (true) {
        sleep(2);
        if ($tick) $toSend = "TICK "; else $toSend = "TOCK ";
        $tick = !$tick;
        $toSend .= time();
        $num_bytes = fwrite($client, $toSend);
        if ($num_bytes === false || $num_bytes < strlen($toSend)) { echo "fwrite() error\n"; continue; }
        else echo "Data sent: {$toSend}. Bytes: {$num_bytes}\n";
    }
    if (fclose($client)) echo "Socket closed\n";
    else echo "fclose() error\n";
?>


问题是:如果我手动关闭服务器(以模拟断开的连接),在服务器关闭后的第一个fwrite()调用(在客户端)不会抛出错误。第二次调用fwrite()将返回0,并按预期生成PHP通知“PHP notice:fwrite():发送15字节失败,错误号为32断开管道”。第一个fwrite()调用发送的所有内容都将丢失,但客户端“认为”一切正常。在生产环境中,出错后,客户端将尝试重新连接,如果成功,它将尝试重新发送数据。但在这里,客户并不完全了解情况。为什么fwrite()的行为是这样的?我试图在流上启用阻塞模式,使用timeout,fwrite(),然后获取流元数据,但似乎fwrite()从未超时,即使它给出错误。有什么建议或解决方案吗?

嗨,我现在面临着同样的问题。你发现你的问题了吗?我正在运行ubuntu和CakePHP,使用带fwrite的套接字。是的,我已经实现了简单的ACK协议。服务器必须用ACK消息响应它接收到的每个命令,以便客户端知道服务器是否接收到它。当并没有ACK时,客户机会假定连接已断开,若您正确地实现了该解决方案,则这一点是正确的。