PHP socket 编程: select同步非阻塞多路复用模式
php作为一个效率一般的单线程语言,用来做socket服务器确实有点勉强,不过php还是提供了各种相关函数,使其可以完整地实现socket编程的各项功能。
// Create a new socket
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$server['host'] = '127.0.0.1';
$server['port'] = '2013';
socket_bind($socket,$server['host'],$server['port']);
socket_listen($socket);
...
首先需要生成一个服务器端socket,并绑定到某主机、端口。注意,一定要将该socket设为非阻塞的。否则socket在accept等待新连接时程序将会被阻塞.
socket_set_nonblock($socket);
一个socket服务端必然需要同时为多个客户端提供服务,单线程的php 的socket模块提供了select的多路复用模型来解决这一问题。
//复制一份客户端列表,socket_select函数的引用参数
$read = $this->clients;
while ( @socket_select($read, $write = NULL, $except = NULL,2) < $this->maxClient ) {
//从连接池中选取一个socket资源
$newc = $this->selectClient( $read,$socket );
if ( $newc === false )
break ;
...
当程序发现有一个新的客户端socket连接服务端时,就将该socket加入select的连接池,等待服务端提供服务,需要注意,加入的客户端socket也需要设为非阻塞,否则客户端在等待服务端读取其缓冲区中的数据时也会将线程阻塞。
当客户端发出退出信号时,服务端将该客户端socket从连接池中去除,socket连接断开。
完成编程后,可用telnet作为客户端对该服务端进行测试。
另外,依靠PHP 的 libevent 扩展(需配置安装),也可以实现 epoll/kqueue 的异步非阻塞I/O模型,性能上会表现的更加优秀。
页:
[1]