亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

您的位置:首頁技術文章
文章詳情頁

用PHP的Socket建立自己的聊天室服務器

瀏覽:3日期:2024-02-21 13:02:42

<?PHP/*** patServer* PHP socket server base class* Events that can be handled:** onStart** onConnect** onConnectionRefused** onClose** onShutdown** onReceiveData** @version 1.1* @authorStephan Schmidt <[email protected]>* @package patServer*/class patServer{/*** information about the project* @var array $systemVars*/var $systemVars= array(

'appName'=> 'patServer', 'appVersion'=> '1.1', 'author'=> array('Stephan Schmidt <[email protected]>', ) );

/*** port to listen* @var integer$port*/ var $port= 10000;

/*** domain to bind to* @var string $domain*/ var $domain= 'localhost';

/*** maximum amount of clients* @var integer $maxClients*/ var $maxClients = -1;

/*** buffer size for socket_read* @var integer $readBufferSize*/ var $readBufferSize= 128;

/*** end character for socket_read* @var integer $readEndCharacter*/ var $readEndCharacter = 'n';

/*** maximum of backlog in queue* @var integer $maxQueue*/ var $maxQueue = 500;

/*** debug mode* @var boolean $debug*/ var $debug= true;

/*** debug mode* @var string $debugMode*/ var $debugMode = 'text';

/*** debug destination (filename or stdout)* @var string $debugDest*/ var $debugDest = 'stdout';

/*** empty array, used for socket_select* @var array $null*/ var $null= array();

/*** all file descriptors are stored here* @var array $clientFD*/ var $clientFD = array();

/*** needed to store client information* @var array $clientInfo*/ var $clientInfo = array();

/*** needed to store server information* @var array $serverInfo*/ var $serverInfo = array();

/*** amount of clients* @var integer$clients*/ var $clients = 0;

/*** create a new socket server** @access public* @param string$domaindomain to bind to* @param integer$portport to listen to*/function patServer( $domain = 'localhost', $port = 10000 ){ $this->domain = $domain; $this->port= $port;

$this->serverInfo['domain'] = $domain; $this->serverInfo['port'] = $port; $this->serverInfo['servername'];;= $this->systemVars['appName']; $this->serverInfo['serverversion'] = $this->systemVars['appVersion'];

set_time_limit( 0 );}

/*** set maximum amount of simultaneous connections** @access public* @param int $maxClients*/function setMaxClients( $maxClients ){ $this->maxClients = $maxClients;}

/*** set debug mode** @access public* @param mixed $debug [text|htmlfalse]* @param string $dest destination of debug message (stdout to output or filename if log should be written)*/function setDebugMode( $debug, $dest = 'stdout' ){ if( $debug === false ){ $this->debug = false; return true; }

$this->debug= true; $this->debugMode = $debug; $this->debugDest = $dest;}

/*** start the server** @access public* @param int $maxClients*/function start(){ $this->initFD = @socket_create( AF_INET, SOCK_STREAM, 0 ); if( !$this->initFD ) die( 'patServer: Could not create socket.' );

// adress may be reused socket_setopt( $this->initFD, SOL_SOCKET, SO_REUSEADDR, 1 );

// bind the socket if(!@socket_bind( $this->initFD, $this->domain, $this->port ) ){ @socket_close( $this->initFD ); die( 'patServer: Could not bind socket to '.$this->domain.' on port '.$this->port.' ( '.$this->getLastSocketError( $this->initFd ).' ).' ); }

// listen on selected port if(!@socket_listen( $this->initFD, $this->maxQueue ) ) die( 'patServer: Could not listen ( '.$this->getLastSocketError( $this->initFd ).' ).' );

$this->sendDebugMessage( 'Listening on port '.$this->port.'. Server started at '.date( 'H:i:s', time() ) );

// this allows the shutdown function to check whether the server is already shut down $GLOBALS['_patServerStatus'] = 'running'; // this ensures that the server will be sutdown correctly register_shutdown_function( array( $this, 'shutdown' ) );

if( method_exists( $this, 'onStart' ) ) $this->onStart();

$this->serverInfo['started'] = time(); $this->serverInfo['status']= 'running';

while( true ){ $readFDs = array(); array_push( $readFDs, $this->initFD );

// fetch all clients that are awaiting connections for( $i = 0; $i < count( $this->clientFD ); $i++ ) if( isset( $this->clientFD[$i] ) ) array_push( $readFDs, $this->clientFD[$i] );

// block and wait for data or new connection $ready = @socket_select( $readFDs, $this->null, $this->null, NULL );

if( $ready === false ){ $this->sendDebugMessage( 'socket_select failed.' ); $this->shutdown(); }

// check for new connection if( in_array( $this->initFD, $readFDs ) ){ $newClient = $this->acceptConnection( $this->initFD );

// check for maximum amount of connections if( $this->maxClients > 0 ){ if( $this->clients > $this->maxClients ){ $this->sendDebugMessage( 'Too many connections.' );

if( method_exists( $this, 'onConnectionRefused' ) ) $this->onConnectionRefused( $newClient );

$this->closeConnection( $newClient ); } }

if( --$ready <= 0 ) continue; }

// check all clients for incoming data for( $i = 0; $i < count( $this->clientFD ); $i++ ){ if( !isset( $this->clientFD[$i] ) ) continue;

if( in_array( $this->clientFD[$i], $readFDs ) ){ $data = $this->readFromSocket( $i );

// empty data => connection was closed if( !$data ){ $this->sendDebugMessage( 'Connection closed by peer' ); $this->closeConnection( $i ); }else{ $this->sendDebugMessage( 'Received '.trim( $data ).' from '.$i );

if( method_exists( $this, 'onReceiveData' ) ) $this->onReceiveData( $i, $data ); } } } }}

/*** read from a socket** @access private* @param integer $clientId internal id of the client to read from* @return string $datadata that was read*/function readFromSocket( $clientId ){ // start with empty string $data= '';

// read data from socket while( $buf = socket_read( $this->clientFD[$clientId], $this->readBufferSize ) ){ $data .= $buf;

$endString = substr( $buf, - strlen( $this->readEndCharacter ) ); if( $endString == $this->readEndCharacter ) break; if( $buf == NULL ) break; }

if( $buf === false ) $this->sendDebugMessage( 'Could not read from client '.$clientId.' ( '.$this->getLastSocketError( $this->clientFD[$clientId] ).' ).' );

return $data;}

/*** accept a new connection** @access public* @param resource &$socket socket that received the new connection* @return int;$clientID internal ID of the client*/function acceptConnection( &$socket ){ for( $i = 0 ; $i <= count( $this->clientFD ); $i++ ){ if( !isset( $this->clientFD[$i] ) || $this->clientFD[$i] == NULL ){ $this->clientFD[$i] = socket_accept( $socket ); socket_setopt( $this->clientFD[$i], SOL_SOCKET, SO_REUSEADDR, 1 ); $peer_host = ''; $peer_port = ''; socket_getpeername( $this->clientFD[$i], $peer_host, $peer_port ); $this->clientInfo[$i] = array( 'host'=> $peer_host, 'port'=> $peer_port, 'connectOn' => time() ); $this->clients++;

$this->sendDebugMessage( 'New connection ( '.$i.' ) from '.$peer_host.' on port '.$peer_port );

if( method_exists( $this, 'onConnect' ) ) $this->onConnect( $i ); return $i; } }}

/*** check, whether a client is still connected** @access public* @param integer $id client id* @return boolean $connected true if client is connected, false otherwise*/function isConnected( $id ){ if( !isset( $this->clientFD[$id] ) ) return false; return true;}

/*** close connection to a client** @access public* @param int $clientID internal ID of the client*/function closeConnection( $id ){ if( !isset( $this->clientFD[$id] ) ) return false;

if( method_exists( $this, 'onClose' ) ) $this->onClose( $id );

$this->sendDebugMessage( 'Closed connection ( '.$id.' ) from '.$this->clientInfo[$id]['host'].' on port '.$this->clientInfo[$id]['port'] );

@socket_close( $this->clientFD[$id] ); $this->clientFD[$id] = NULL; unset( $this->clientInfo[$id] ); $this->clients--;}

/*** shutdown server** @access public*/function shutDown(){ if( $GLOBALS['_patServerStatus'] != 'running' ) exit; $GLOBALS['_patServerStatus'] = 'stopped';

if( method_exists( $this, 'onShutdown' ) ) $this->onShutdown();

$maxFD = count( $this->clientFD ); for( $i = 0; $i < $maxFD; $i++ ) $this->closeConnection( $i );

@socket_close( $this->initFD );

$this->sendDebugMessage( 'Shutdown server.' ); exit;}

/*** get current amount of clients** @access public* @return int $clients amount of clients*/function getClients(){ return $this->clients;}

/*** send data to a client** @access public* @param int$clientId ID of the client* @param string $datadata to send* @param boolean $debugData flag to indicate whether data that is written to socket should also be sent as debug message*/function sendData( $clientId, $data, $debugData = true ){ if( !isset( $this->clientFD[$clientId] ) || $this->clientFD[$clientId] == NULL ) return false;

if( $debugData ) $this->sendDebugMessage( 'sending: '' . $data . '' to: $clientId' );

if(!@socket_write( $this->clientFD[$clientId], $data ) ) $this->sendDebugMessage( 'Could not write ''.$data.'' client '.$clientId.' ( '.$this->getLastSocketError( $this->clientFD[$clientId] ).' ).' );}

/*** send data to all clients** @access public* @param string $datadata to send* @param array $exclude client ids to exclude*/function broadcastData( $data, $exclude = array(), $debugData = true ){ if( !empty( $exclude ) && !is_array( $exclude ) ) $exclude = array( $exclude );

for( $i = 0; $i < count( $this->clientFD ); $i++ ){ if( isset( $this->clientFD[$i] ) && $this->clientFD[$i] != NULL && !in_array( $i, $exclude ) ){ if( $debugData ) $this->sendDebugMessage( 'sending: '' . $data . '' to: $i' );

if(!@socket_write( $this->clientFD[$i], $data ) ) $this->sendDebugMessage( 'Could not write ''.$data.'' client '.$i.' ( '.$this->getLastSocketError( $this->clientFD[$i] ).' ).' ); } }}

/*** get current information about a client** @access public* @param int$clientId ID of the client* @return array $infoinformation about the client*/function getClientInfo( $clientId ){ if( !isset( $this->clientFD[$clientId] ) || $this->clientFD[$clientId] == NULL ) return false; return $this->clientInfo[$clientId];}

/*** send a debug message** @access private* @param string $msg message to debug*/function sendDebugMessage( $msg ){ if( !$this->debug ) return false;

$msg = date( 'Y-m-d H:i:s', time() ) . ' ' . $msg;

switch( $this->debugMode ){ case 'text': $msg = $msg.'n'; break; case 'html': $msg = htmlspecialchars( $msg ) . '<br />n'; break; }

if( $this->debugDest == 'stdout' || empty( $this->debugDest ) ){ echo $msg; flush(); return true; }

error_log( $msg, 3, $this->debugDest ); return true;}

/*** return string for last socket error** @access public* @return string $error last error*/function getLastSocketError( &$fd ){ $lastError = socket_last_error( $fd ); return 'msg: ' . socket_strerror( $lastError ) . ' / Code: '.$lastError;}function onReceiveData($ip,$data){ $this->broadcastData( $data,array(), true );}}$patServer = new patServer();$patServer->start();?>

標簽: PHP
主站蜘蛛池模板: 青木玲中文字幕一区二区 | 新国产视频 | 色毛片| 丰满大乳女啪啪中文字幕 | 日本成人片网站 | 一级黄色性片 | 久久精品久久精品 | 99久久精品自在自看国产 | 深夜福利1000 | 国产一级性生活片 | 高清黄色毛片 | 国产日韩第一页 | 黄网站在线观看永久免费 | 国产三级三级三级三级 | 激情婷婷网 | 午夜国产福利在线 | 久久精品影院一区二区三区 | 在线播放免费人成毛片乱码 | 欧美一区二区三区在线播放 | 色哟永久免费 | 自拍亚洲一区 | 丰满老妇猛交视频 | 国产毛片一区二区三区 | 日本成本人啪啪黄3d动漫 | 日本二本三本二区 | 国产精品嫩草影院在线观看免费 | 一区二区高清在线观看 | 欧美黄色片 一级片 | 国产理论最新国产精品视频 | 成人在线精品视频 | 国语对白清晰好大好白在线 | 亚洲精品99久久一区二区三区 | 1024 在线观看视频免费 | 国产成 人 综合 亚洲绿色 | 国产一区不卡 | 丁香婷婷久久大综合 | 99pao成人国产永久免费视频 | 欧美黄色大片网站 | 午夜性视频播放免费视频 | 美女一区二区在线观看 | 欧美黄色免费看 |