服务端:
<?php $socket = stream_socket_server('tcp://127.0.0.1:8888', $errno, $errstr); while ($conn = stream_socket_accept($socket)) { fwrite($conn, "1024"); fclose($conn); } fclose($socket);
客户端:
<?php $socket = stream_socket_client('tcp://127.0.0.1:8888', $errorno, $errstr); while (!feof($socket)) { echo fread($socket, 128); } fclose($socket);
这是一个很经典的socket的客户端和服务端,由于客户端不知道服务器端发送了多少数据,通过feof()判断是否读取完成。但是feof如果遇到一个socket套接字,并且这个套接字没有被关闭,就算读取不到数据也会一直阻塞等待不会继续执行,一直到最终超时,而超时的配置由php.ini的default_socket_timeout时间决定,也可以通过stream_set_timeout对单独的套接字设置超时时间。下面给出验证代码:
我们将服务器端代码改为如下:
<?php $socket = stream_socket_server('tcp://127.0.0.1:8888', $errno, $errstr); while ($conn = stream_socket_accept($socket)) { fwrite($conn, "1024"); } fclose($socket);
此时客户端获取到1024的数据后会一直阻塞不能退出进程,因为服务器端发送完数据没有关闭客户端。而服务器端关闭客户端可以用fclose或者unset或者设置为null。通常我们不建议用feof来获取socket发送的数据,建议使用指定协议或者指定发送大小来解决问题。
另外feof在传递的文件指针无效的时候为一直返回true,你很有必要使用is_resource来判断一下,不正确的处理会陷入死循环。