这个类,现在在linux下,只能高于5.2的版本才能正常使用。 例子<?php include("TcpServer.class.php"); class Security extends TcpServerHandle{ var $init_string ='<?xml version="1.0" encoding="UTF-8"?><cross-domain-policy><allow-access-from domain="*" to-ports="80,999 8,10000,10001,10002"/></cross-domain-policy>'; public function HandleNewConnection(){ // print_r("CT:".count($this->getClients())."\n"); $this->write("Welcome...\n"); //$this->close(); } public function HandleData($data){ echo "RECV{{$data}},LEN{".strlen($data)."}\n"; $this->write("You Send:$data"); } } $server = new TcpServer($argv[1]); $server->max_clients = 1000; $server->bind("Security"); $server->run(); ?> TcpServer类 TcpServer<?php /* +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2008 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Authors: Hetal +----------------------------------------------------------------------+ */ class TcpServerHandle{ /** * 所有属性全是只读,请不要修改 **/ /** * 当前所有连接 **/ //var $_clients;//所有在线的人的sock /** * 当前连接socket **/ var $_sock; /** * 当前连接的ID号 **/ var $id; /** * 当前连接的客户端ip **/ var $ip; /** * 当前连接的客户端磁口 */ var $port; /** * 新连接进入时调用 **/ public function HandleNewConnection(){ } /** * 有数据可读时调用 **/ public function HandleData($data){ } /** * 连接断开时调用 **/ public function HandledisConnected(){ } /** * 写数据 **/ public function write($data){ return stream_socket_sendto($this->_sock,$data); } /** * 关闭连接 **/ public function close(){ fclose($this->_sock); unset(TcpServer::$_clients[$this->_sock]); unset(TcpServer::$_objects[$this->_sock]); } /** * 获取服务端所有连接 **/ public function getClients(){ return TcpServer::$_clients; } } /** * */ class TcpServer{ /** * 最大连接数,linux支持1000 **/ var $max_clients = 150; /** * 主要socket **/ private $_sock; private $_objectName; private $_port; static $_objects; static $_clients; public function __construct($port=9999){ $this->_port = $port; } public function __desctruct(){ fclose($this->_sock); } public function bind($objectName){ $this->_objectName = $objectName; } public function run(){ $this->_sock = stream_socket_server("tcp://0.0.0.0:".$this->_port, $errno, $errstr); if(!$this->_sock){ die( "$errstr ($errno)<br />\n"); } stream_set_blocking ($this->_sock,1); TcpServer::$_clients = array(); TcpServer::$_clients[$this->_sock] = $this->_sock; while (true) { $read = TcpServer::$_clients; if (false===($num_changed_streams = stream_select($read, $write = NULL, $except = NULL, NULL))){ continue; }elseif($num_changed_streams>0){ for ($i = 0; $i < $num_changed_streams; ++$i) { if ($read[$i] === $this->_sock) { //新连接 if(false !==($newsock = stream_socket_accept($this->_sock))){ if(count(TcpServer::$_clients)>$this->max_clients){ echo count(TcpServer::$_clients).":"."超过了限制[".$this->max_clients."]了\n"; fclose($newsock); }else{ stream_set_timeout($newsock, 2); $socket_name = explode(":", stream_socket_get_name($newsock,true)); TcpServer::$_objects[$newsock] = new $this->_objectName; TcpServer::$_objects[$newsock]->_sock = $newsock; TcpServer::$_objects[$newsock]->id = (int)$newsock; TcpServer::$_objects[$newsock]->ip = $socket_name[0]; TcpServer::$_objects[$newsock]->port = $socket_name[1]; TcpServer::$_clients[$newsock] = $newsock; $command="HandleNewConnection"; if(method_exists (TcpServer::$_objects[$newsock],$command)){ call_user_func_array(array(&TcpServer::$_objects[$newsock], $command), array()); } } } }else{ $read_sock = $read[$i]; $data = ""; while(($c=fgetc($read_sock))!==false && $c!="\0" && $c!="\n" && $c!="\r"){ $data .=$c; } if ($c === false) { $info = stream_get_meta_data($read_sock); if ($info['timed_out']) { fclose($read_sock); } $command="HandledisConnected"; if(method_exists (TcpServer::$_objects[$read_sock],$command)){ call_user_func_array(array(&TcpServer::$_objects[$read_sock], $command), array());//, array($read_sock)); } unset(TcpServer::$_objects[$read_sock]); unset(TcpServer::$_clients[$read_sock]); continue; }elseif($data!=""){ $command = "HandleData"; if(method_exists (TcpServer::$_objects[$read_sock],$command)){ call_user_func_array(array(&TcpServer::$_objects[$read_sock], $command), array($data)); } } } } } } } } ?> |