stream_set_blocking函数可以将资源流设置为阻塞模式或者非阻塞模式,主要影响的函数分别是fgets,fread,其他的手册没有说。
在socket编程中,如果一个socket连接上了,但是不发送数据,此时使用fread或者fgets去读取数据,由于socket句柄是有效的,但是获取不到数据,fread/fgets就会阻塞等待卡在那里,一直等到超时才继续向下执行。
看下面的阻塞等待demo:
服务器:
<?php $socket = stream_socket_server('tcp://127.0.0.1:8888', $errno, $errstr); while ($conn = stream_socket_accept($socket)) { //服务端知道客户端连接了,就是不给你发消息,先睡一会儿吧 sleep(1000); } fclose($socket);
客户端:
<?php $socket = stream_socket_client('tcp://127.0.0.1:8888', $errorno, $errstr); echo 'start'; echo fread($socket, 128); echo 'success'; fclose($socket);
由于服务器端不发送任何东西,fread一直卡住,阻塞等待,此时程序只输出start,一直到超时后才输出success。另外需要注意的是阻塞等待过程中如果对应的socket被关闭了也不会继续阻塞,例如上面的服务器端被关闭了。
再看下面的非阻塞等待demo:
客户端:
<?php $socket = stream_socket_client('tcp://127.0.0.1:8888', $errorno, $errstr); stream_set_blocking($socket,false); echo 'start'; echo fread($socket, 128); echo 'success'; fclose($socket);
非阻塞等待的比较简单,我去获取数据,没有就算了直接返回,根本不去等你给我发。