|
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模型,性能上会表现的更加优秀。 |
|