使 stream_socket_server 在第一次收到数据包后保持功能

Make stream_socket_server to stay functional after first received data package

我正在尝试让 tcp 套接字服务器通过 PHP 的 stream_socket_server().

创建和维护持久的双向通信

Short version of question:

how to have tcp server created with stream_socket_server() staying alive - not failing to receive data after first successful data reception which is in my case one single character typed in terminal after telnet command?

长版 - 我期望达到的效果

仅供参考,查看使用 smtp 服务器远程登录某些主机时的通信类型。您输入终端 telnet somehost 25 并获得欢迎回复和(通常)smtp 横幅。 并且连接持续存在。 比起您键入 hello 命令,您会再次收到带有继续发出进一步命令的选项的响应。 同样,连接仍然存在,您收到响应并选择继续。这正是我所追求的沟通方式。

到目前为止我做了什么

此代码:

<?php

$server = stream_socket_server("tcp://0.0.0.0:4444", $errno, $errorMessage);

if ($server === false) throw new UnexpectedValueException("Could not bind to socket: $errorMessage");

for (;;)  {
    $client = stream_socket_accept($server);

    if ($client) 
    {
        echo 'Connection accepted from ' . stream_socket_get_name($client, false) . "\n";
        echo "Received Out-Of-Band: " . fread($client, 1500) . "\n";
        #fclose($client);
    } 

}

如果您只是尝试通过另一个 PHP 脚本发送数据(每次拍摄一次),即 stream_socket_client().

此脚本创建的服务器无法维持我所描述的连接类型。完成 telnet localhost 4444 后,我切换到终端模式来写消息。当我这样做时,在服务器端 我第一个输入的字符被捕获了,仅此而已 。无论我尝试过什么,我都无法通过键入来捕获从客户端发送的新包。像 stream_socket_accept() 在收到第一个字符数据包后阻止或忽略所有内容。 那么,我做错了什么 - 如何解决这个问题?

您的程序在循环返回以接受另一个传入连接之前只进行一次读取。

documentation for fread 表示一旦收到数据包就会return。也就是说,它不会等待完整的 1500 个字节。

鉴于人类打字的速度很慢,您最终会向您的服务器发送一个包含单个字符的数据包,该数据包 returned 然后它继续接受另一个传入连接。

像这样围绕你的阅读进行循环:

for (;;)  {
    $client = stream_socket_accept($server);

    if ($client) {
        echo 'Connection accepted from ' . stream_socket_get_name($client, false) . "\n";
        for (;;) {
            $data = fread($client, 1500);
            if ($data == '') break;
            echo "Received Out-Of-Band: " . $data . "\n";
        }
        fclose($client);
    } 
}