我试图通过PHP的stream_socket_server()使tcp服务器创建和维护持久的双向通信。
问题的简短版本: 如何在
stream_socket_server()仍然活着的情况下创建tcp服务器--在第一次成功的数据接收(在我的例子中,是在telnet命令后输入终端中的一个字符)之后,不失败地接收数据?
长版本-我到底希望实现什么
仅为说明起见,请查看使用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()一样,在接收到第一个字符数据包后,就会忽略所有这些。那么,我做错了什么-如何解决这个问题?
发布于 2015-04-25 13:07:12
您的程序在返回以接受另一个传入连接之前只进行了一次读取。
fread文件声明,它将在收到数据包后立即返回。也就是说,它不会等待完整的1500字节。
考虑到人工输入的速度缓慢,您最终会向服务器发送一个只有一个字符的数据包,该数据包将被返回,然后它将接受另一个传入连接。
在读到的内容周围放一个循环:
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);
}
}https://stackoverflow.com/questions/29788501
复制相似问题