使 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);
}
}
我正在尝试让 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);
}
}