<?php
/*
*********************************************************************************
*Itrebal Creations PHP Server Class *
*Copyright (C) 2005 Graham Christensen *
*Email itrebal@gmail.com IRC: itrebal@freenode.net AIM: itrebal *
*Website: www.itrebal.com *
* *
*This program is free software; you can redistribute it and/or *
*modify it under the terms of the GNU General Public License *
*as published by the Free Software Foundation; either version 2 *
*of the License, or any later version. *
* *
*This program is distributed in the hope that it will be useful, *
*but WITHOUT ANY WARRANTY; without even the implied warranty of *
*MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
*GNU General Public License for more details. *
* *
*You should have received a copy of the GNU General Public License *
*along with this program; if not, write to the Free Software *
*Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.*
*********************************************************************************
*/
class server{
public $clients;
public $active_clients;
public $socket;
public $ip;
public $port;
public $max_clients;
public $crlf;
public $version;
public $run_msg;
public $hello_msg;
function server($ip,$port,$max_clients){
$this->ip = $ip;
$this->port = $port;
$this->max_clients = $max_clients;
$this->clients = array();
$this->active_clients = 0;
$this->socket = '';
$this->version = '1.0.0';
$this->crlf = "\r\n";
set_time_limit(0);
@ob_end_clean();
}
function create_socket(){
$socket = socket_create(AF_INET,SOCK_STREAM,0);
$port = $this->port;
while(!socket_bind($socket,$this->ip,$port)){
$port++;
}
$this->port = $port;
socket_listen($socket);
$this->socket = $socket;
}
function display($echo){
echo $echo."\n";
}
function new_client($socket){
if($this->active_clients < $this->max_clients){
$this->clients[$this->active_clients] = array();
$this->set_socket($this->active_clients, socket_accept($socket));
$this->reset_input($this->active_clients);
socket_getpeername($this->get_socket($this->active_clients), &$ip,&$port);
$set = $ip.':'.$port;
$this->set_addr($this->active_clients, $set);
//
//Say hello
//
//Loop through and send it
foreach($this->hello_msg as $line){
$this->send($this->active_clients, $line);
}
$this->socket_setnonblock($this->active_clients);
//Make the server log happy
$this->logit('['.$this->get_addr($this->active_clients).'] Connected');
$this->active_clients++;
}
}
function get_socket($i){
return $this->clients[$i]['sock'];
}
function set_socket($i,$socket){
$this->clients[$i]['sock'] = $socket;
}
function get_addr($i){
return $this->clients[$i]['address'];
}
function set_input($i, $input){
$this->clients[$i]['input'] = $input;
}
function get_input($i){
return $this->clients[$i]['input'];
}
function reset_input($i){
$this->clients[$i]['input'] = '';
}
function read_socket($i){
if(is_bool(@socket_recv($this->clients[$i]['sock'],$buf,1024,0))){
return FALSE;
}else{
return $buf;
}
}
function kick($i){
$this->logit('['.$this->get_addr($i).'] disconnected');
@socket_close($this->clients[$index]['sock']);
$this->clients[$i] = $this->clients[--$this->active_clients];
array_pop($this->clients);
}
function socket_end(){
socket_close($this->socket);
}
function set_addr($i,$addr){
$this->clients[$i]['address'] = $addr;
}
function socket_setnonblock($i){
socket_set_nonblock($this->clients[$i]['sock']);
}
function send($i,$msg){
@socket_send($this->clients[$i]['sock'],$msg.$this->crlf,strlen($msg),0);
}
function logit($msg){
echo '['.date('m/d/Y H:i:s').'] '.$msg."\n";
}
function run(){
$this->create_socket();
$this->display('Itrebal Creations PHP Server Running on Port '.$this->port);
while(true){
$read = array();
$i = 0;
$read[0] = $this->socket;
$clients = $this->clients;
foreach($clients as $val){
$read[++$i] = $val['sock'];
}
$ready = socket_select($read, $write, $except,0);
// Handle new clients
if(in_array($this->socket,$read)){
$this->new_client($this->socket);
}
// Serve clients
for($i=0;$i < $this->active_clients;$i++){
if(in_array($this->get_socket($i),$read)){
// Append input
$temp = $this->read_socket($i);
if(is_bool($temp)){
$this->kick($i);
continue;
}
$input = $this->get_input($i).$temp;
// Apply backspaces
$input = preg_replace("/(^|.)\\x08/","",$input);
// IF END OF STRING = <crlf>
if(preg_match("/[\\015\\012]{2}$/",$input)){
// Kick <crlf> and trailing spaces
$input = preg_replace("/[ \\015\\012]+$/","",$input);
if($input == ''){
$this->reset_input($i);
}else{
// Evaluate input
$this->set_input($i,$input);
evaluate($i); //processes the input and decides on the output..The meat
$this->reset_input($i);
}
}else{
$this->set_input($i,$input);
}
}
}
}
// Close master sockets
$this->socket_end();
}
}
?>