Скрипт внезапно умирает.

Статус
В этой теме нельзя размещать новые ответы.

kode

never knows best
Скрипт внезапно умирает.

Есть код (вобще это много файлов, но всё слил в один):
PHP:
<?php

//ini_set("display_errors",0);

<?php

/**
 * Базовый класс реализующий низкоуровневую работу с сокетам
 * @author [email][email protected][/email]
 * @todo Переделать исключения, нужно сделать на основе наследуюмых исключений
 * @version 1.0
 */
class Socket{
	/**
	 * socket handler
	 *
	 * @var resource
	 */
	protected $socket;

	/**
	 * Domain AF_INET, AF_INET6 or AF_UNIX
	 *
	 * @var int
	 */
	protected $domain;
	
	/**
	 * Type of communication of socket - SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET, SOCK_RAW or SOCK_RDM
	 *
	 * @var int
	 */
	protected $type;
	
	/**
	 * Protocol (TCP, UDP, ICMP) of socket - SOL_TCP, SOL_UDP or 1 (ICMP)
	 *
	 * @var int
	 */
	protected $protocol;
	
	/**
	 * Local hostname
	 *
	 * @var string
	 */
	public $localhost;	
	
	/**
	 * Local port
	 *
	 * @var int
	 */
	public $localport;
	
	/**
	 * Remote host
	 *
	 * @var string
	 */
	public $peerhost;
	
	/**
	 * Remote port
	 *
	 * @var int
	 */
	public $peerport;

	/**
	 * Blocking mode
	 *
	 * @var boolean
	 */
	protected $blocking;
	
	/**
	 * Initialize sockets
	 *
	 * @param int $domain
	 * @param int $type
	 * @param int $protocol
	 * @throws Exception
	 */
	public function __construct($domain=AF_INET,$type=SOCK_STREAM,$protocol=SOL_TCP){
		if(!function_exists("socket_create")){
			throw new Exception("No sockets Extension installed. Please add 'extenstion=sockets.[so|dll]' to php.ini, or recompile PHP with '--with-sockets'");
		}

		$this->domain = $domain;
		$this->type = $type;
		$this->protocol = $protocol;
		//By default sockets is 'blocking'
		$this->blocking = true;

		$this->create();
		if(!$this->socket){
			throw new Exception($this->getError());
		}
	}

	/**
	 * Gracefuly close socket
	 */
	public function __destruct(){
		if(is_resource($this->socket)){
			$this->close();
		}
	}

	/**
	 * Binds a socket
	 *
	 * @param int $port
	 * @param string $address
	 * @return boolean
	 * @throws Exception
	 */
	public function bind($port=0,$address=0){
		if(!$result =($port)?socket_bind($this->socket,$address,$port):socket_bind($this->socket,$address)){
			throw new Exception($this->getError());
		}
		$this->address = $address; $this->port = $port;
		return $result;
	}

	/**
	 * Accepts new connection and returns new socket
	 * @return resource
	 * @throws Exception
	 */
	public function accept(){
		$newsocket = socket_accept($this->socket);
		if($this->blocking and !$newsocket){ //Error cause
			throw new Exception($this->getError());
		}
		return $newsocket;
	}

	/**
	 * Set Blocking mode
	 *
	 * @param boolean $mode
	 * @return boolean
	 * @throws Exception
	 */
	public function blocking($mode){
		$result = ($mode)?socket_set_block($this->socket):socket_set_nonblock($this->socket);
		if(!$result){
			throw new Exception($this->getError());
		}
		$this->blocking = $mode;
		return $result;
	}

	/**
	 * Sets socket to listening mode for new connections
	 *
	 * @return boolean
	 * @throws Exception
	 */
	public function listen(){
		if(!socket_listen($this->socket)){
			throw new Exception($this->getError());
		}
		$this->getPeerInfo();
		$this->getSockInfo();
		return true;
	}

	/**
	 * Initiates a connection on a socket
	 *
	 * @param int $host
	 * @param string $port
	 * @return boolean
	 * @throws Exception
	 */
	public function connect($host,$port=null){
		if(!socket_connect($this->socket,$host,$port)){
			throw new Exception($this->getError());
		}
		$this->getPeerInfo();
		$this->getSockInfo();
		return true;
	}
	
	/**
	 * Sends data to remote socket
	 *
	 * @param string $data
	 * @param int $len
	 * @return int data written
	 * @throws Exception
	 */
	public function send($data,$len=false){
		$len = (!$len)?strlen($data):$len;
		$return = socket_write($this->socket,$data,$len);
		if($return === false){
			throw new Exception($this->getError());
		}
		return $return;
	}
	
	/**
	 * Reads data from remote socket
	 *
	 * @param int $length
	 * @param int $type
	 * @return string data fetched
	 * @throws Exception
	 */
	public function read($length=1024,$type=PHP_BINARY_READ){
		$data = socket_read($this->socket,$length,$type);
		if($data === false){
			throw new Exception($this->getError());
		}
		return $data;
	}

	/**
	 * Get remote socket info
	 *
	 * @return boolean
	 */
	protected function getPeerInfo(){
		return socket_getpeername($this->socket,$this->peerhost,$this->peerport);
	}
	
	/**
	 * Get local socekt info
	 *
	 * @return boolean
	 */
	protected function getSockInfo(){
		return socket_getsockname($this->socket,$this->localhost,$this->localport);
	}
	
	/**
	 * Return last error
	 *
	 * @return string
	 */
	protected function getError(){
		return socket_strerror(socket_last_error($this->socket));
	}
	
	/**
	 * Create new socket
	 *
	 * @return resource
	 */
	protected function create(){
		if($this->socket){
			$this->close();
		}		
		return $this->socket = socket_create($this->domain,$this->type,$this->protocol);
	}
	
	/**
	 * Close socket
	 *
	 */
	protected function close(){
		socket_shutdown($this->socket,2);
		socket_close($this->socket);		
	}

}

/**
 * Промежуточный класс реализовывающий клиентскую часть
 * @author [email][email protected][/email]
 * @todo Расширить функциональность
 *
 */
class clientSocket extends Socket {
	
	protected $host, $port;
	
	public function __construct($host,$port){
		parent::__construct();
		try {
			$this->connect($host,$port);
			$this->host = $host; $this->port = $port;
		}catch (Exception $e){
			echo "Error: Cannot connect to {$host}:{$port} :",$e->getMessage();
		}
	}
	
	public function reconnect(){
		//Реинициализируем сокет
		$this->create();
		//Коннектимся
		$this->connect($this->host,$this->port);
	}

	public function readAll(){
		$data = "";
		do{
			$buffer=$this->read();
			$data .= $buffer; 
		}while(!$buffer);
		return $data;
	}
}


/**
 * Класс реализующий работу DC++ протокола
 * @see [url]http://sourceforge.net/docman/display_doc.php?docid=10564&group_id=36589[/url]
 * @author [email][email protected][/email]
 *
 */
class DC extends clientSocket {
	const version = "0,001";
	public $host,$port;

	public $nick;
	public $password;

	protected $start_time;

	public $debug;

	public function __construct($nick='BotMan',$password='',$debug=0){
		$this->nick = $nick;
		$this->password = $password;
		$this->debug = $debug;
	}

	public function connectHub($hub,$port=411){
		parent::__construct($hub,$port);
		$this->start_time = time();
		$this->login();
	}


	protected function login(){
		//Reads until welcome data arrival
		usleep(100); // Stage One - LOGIN
		$this->process();
		$this->sendCommand("ValidateNick",$this->nick);
		sleep(2);    // STAGE TWO
		$this->process(); //Пройдём первый цикл!
		//Теперь надо отослать MyINFO
		$this->sendVersion();
		$this->requestNickList();
		$this->sendMyInfo();
	}

	protected function sendCommand($command,$data=""){
		$data = "\${$command}".(($data)?" {$data}":"")."|";
		echo $data,"\n";
		echo "Written: ",$this->send($data)," bytes\n";
		$this->printDebugMsg("<] {$data}");
		echo "bang!\n";
	}

	public function requestAllInfo($usersarray=null){
		echo "start!";
		foreach ($usersarray as $user){
			$this->requestUserInfo($user);
		}
		echo "end!";
	}

	public function requestNickList(){
		$this->sendCommand("GetNickList");
	}

	public function requestUserInfo($user){
		$this->sendCommand("GetINFO","{$user} {$this->nick}");
	}

	protected function sendVersion(){
		$this->sendCommand("Version",self::version);
	}

	protected function sendMyInfo($who='$ALL'){
		//$MyINFO $ALL <nick> <interest>$ $<speed>$<e-mail>$<sharesize>$
		$data = '$All '.$this->nick.' <desc>$ $DSL'.chr(1).'$$0$';
		$this->sendCommand("MyINFO",$data);
	}


	/**
	 * Функция печати отладочной информации
	 *
	 * @param string $msg
	 */
	function printDebugMsg($msg){
		if($this->debug){
			echo "[DEBUG]",$msg,"\n";
		}
	}

	public function process(){
		$messages = explode("|",$this->readAll());
		foreach ($messages as $message){
			if($message){
				$this->parseMessage($message);
			}
		}
	}

	public function sendMessage($msg){
		$this->send("<{$this->nick}> {$msg}|");
	}

	protected function generateKey($lock){
		$len = strlen($lock);
		$key = str_repeat(" ",$len);
		for ($i=1;$i<$len;$i++){
			$key[$i] = $lock[$i]^$lock[$i-1];
		}
		$key[0] = $lock[0]^$lock[$len-1]^$lock[$len-2]^5;

		for ($i = 0; $i < $len; $i++){
			$key[$i] = (($key[$i]<<4) & 240) | (($key[$i]>>4) & 15);
		}

		$key = str_replace(chr(0),'%DCN000%/',$key);
		$key = str_replace(chr(5),'%DCN005%/',$key);
		$key = str_replace(chr(36),'%DCN036%/',$key);
		$key = str_replace(chr(96),'%DCN096%/',$key);
		$key = str_replace(chr(124),'%DCN124%/',$key);
		$key = str_replace(chr(126),'%DCN126%/',$key);

		return $key;
	}

	protected function parseMyINFO($myinfo){
		//        0    1      2          3 4       5        6        
		//                    0          1 2       3        4  
		//$MyINFO $ALL <nick> <interest>$ $<speed>$<e-mail>$<sharesize>$ 
		print_r($myinfo);
		$data = array('nick'=>$myinfo[1]);
		
		$rawdata = explode("$",implode(" ",array_slice($myinfo,2)));
		print_r($rawdata);
		$data['interest'] = $rawdata[0];
		$data['speed']    = substr($rawdata[2],0,-1);
		$data['email']    = $rawdata[3];
		$data['share']    = $rawdata[4];
		$data['away']     = 0;
		/*
		 1 for normal,
		 2 for away,
		 3 also for away,
		 4 for fileserver,
		 5 also for fileserver,
		 6 for fileserver away,
		 7 also for fileserver away,
		 8 for fireball,
		 9 also for fireball,
		 10 for fireball away
		 and 11 also for fireball away */
		switch (ord(substr($rawdata[2],-1))) {
			//NORMAL
			case 2:
			case 3:
				$data['away'] = 1;
			case 1:
				$data['type'] = 'normal';
			break;
			//FILESERVER
			case 6:
			case 7:
				$data['away'] = 1;
			case 4:
			case 5:
				$data['type'] = 'fileserver';
				break;
			case 10:
			case 11:
				$data['away'] = 1;
			case 8:
			case 9:
				$data['type'] = 'fireball';
				break;
		}
		
		return $data;		
	}

	protected function parseMessage($msg){
		$this->printDebugMsg("[> {$msg}");

		$command = explode(" ",$msg);
		if($command[0][0] == "$"){
			$method = "command".trim(array_shift($command),":$");
			if(method_exists($this,$method)){
				$this->$method($command,implode(" ",$command));
			}elseif($this->debug){
				$this->printDebugMsg("Unsupported message recieved ($msg)");
			}
		}elseif(method_exists($this,"commandMessage")){
			$this->commandMessage(array($msg),$msg);
		}
		echo "oiai!";
	}

	public function disconnect(){
		$this->sendCommand("Quit",$this->nick);
		$this->close();
	}

	public function reconnect(){
		$this->disconnect();
		$this->connect($this->host,$this->port);
	}

	public function __destruct(){
		$this->disconnect();
		parent::__destruct();
	}

}

class DCClient extends DC {

	public $hubname;
	public $hubtopic;

	public $ops = array();
	public $users = array();

	public $showuserexits = 0;
	public $recieve_whispers = 1;

	public $debug = 1;

	protected $start_time;


	public $collected_info = array();

	public function __construct($hub,$nick='BotMan',$password='',$port=411){
		parent::__construct($nick,$password);
		$this->connectHub($hub,$port);
	}

	/**
	 * Функция печати в чат
	 *
	 * @param string $msg
	 */
	function printToChat($msg){
		echo "[",date("H:i:s"),"] ",$msg,"\n";
	}


	/**
	 * Функция из клиентской части
	 * 
	 * Формат исходного сообщения:
	 * Format: $Lock <lockcode> Pk=...
	 *
	 * @param array $params
	 */
	protected function commandLock($params,$rawmessage){
		$key = $this->generateKey($params[0]);
		$this->sendCommand("Key",$key);
	}

	/**
	 * Функция из клиентской части
	 * 
	 * Формат исходного сообщения:
	 * Format: $HubName <hubname>
	 *
	 * @param array $params
	 */
	protected function commandHubName($params,$rawmessage){
		$this->hubname = $rawmessage;
	}

	/**
	 * Функция из клиентской части
	 * 
	 * Формат исходного сообщения:
	 * Format: $ValidateDenide <nick>
	 *
	 * @param array $params
	 */
	protected function commandValidateDenide($params,$rawmessage){
		throw new Exception("Error: '{$rawmessage}' nick is already in use or invalid!");
	}

	/**
	 * Функция из клиентской части
	 * 
	 * Формат исходного сообщения:
	 * Format: $GetPass
	 *
	 * @param array $params
	 */
	protected function commandGetPass($params,$rawmessage){
		if($this->password){
			$this->sendCommand("MyPass",$this->password);
		}else{
			throw new Exception("Error: Hub require password for this nick!");
		}
	}

	/**
	 * Функция из клиентской части
	 * 
	 * Формат исходного сообщения:
	 * Format: $HubTopic <hubtopic>
	 *
	 * @param array $params
	 */
	protected function commandHubTopic($params,$rawmessage){
		$this->hubtopic = $rawmessage;
		$this->printToChat("[HUBTOPIC]: {$this->hubtopic}");
	}

	/**
	 * Функция из клиентской части
	 * 
	 * Формат исходного сообщения:
	 * Format: $BadPass
	 *
	 * @param array $params
	 */
	protected function commandBadPass($params,$rawmessage){
		throw new Exception("[Error]: Invalid password taken!");
	}

	/**
	 * Функция из клиентской части
	 * 
	 * Формат исходного сообщения:
	 * Format: $Hello <nickname>
	 *
	 * @param array $params
	 */
	protected function commandHello($params,$rawmessage){
		$this->requestUserInfo($rawmessage);
		$this->users[] = $rawmessage;
	}

	/**
	 * Функция из клиентской части
	 * 
	 * Формат исходного сообщения:
	 * Format: $LogedIn <nickname>
	 *
	 * @param array $params
	 */
	protected function commandLogedIn($params,$rawmessage){
		$this->printToChat("[+++] Login successful with nick {$rawmessage}");
	}

	/**
	 * Функция из клиентской части
	 * 
	 * Формат исходного сообщения:
	 * $To: <nickname> From: <ownnickname> $<ownnickname> <message>
	 *
	 * @param array $params
	 */
	protected function commandTo($params,$rawmessage){
		if($params[1] == $this->nick and $this->recieve_whispers){ //Сообщение пришло нам
			$this->printToChat("[Whisper]: <{$params[3]}> ".implode(" ",array_slice($params,4)));
		}
	}

	/**
	 * Функция из клиентской части
	 * 
	 * Формат исходного сообщения:
	 * Format: $Quit <nickname>
	 *
	 * @param array $params
	 */
	protected function commandQuit($params,$rawmessage){
		if(in_array($rawmessage,$this->users)){
			$key = array_keys($this->users,$rawmessage);
			unset($this->users[$key[0]]);
		}
		if(in_array($rawmessage,$this->ops)){
			$key = array_keys($this->ops,$rawmessage);
			unset($this->ops[$key[0]]);
		}
		if($this->showuserexits){
			$this->printToChat("[+++] User {$rawmessage} exited!");
		}
	}

	/**
	 * Функция из клиентской части
	 * 
	 * Формат исходного сообщения:
	 * Format: $MyINFO $ALL <nickname> <description>$ $<speed>$<email>$<sharedsizeinbyte>$
	 *
	 * @param array $params
	 */
	protected function commandMyINFO($params,$rawmessage){
		$this->collected_info[$params[1]] = $this->parseMyINFO($params);
	}

	/**
	 * Функция из клиентской части
	 * 
	 * Формат исходного сообщения:
	 * Format: $NickList <nickname1>$$<nickname2>$$...$$<nicknameN>$$
	 *
	 * @param array $params
	 */
	protected function commandNickList($params,$rawmessage){
		$this->users = explode("$$",implode(" ",$params));
		array_pop($this->users); //Удаляем последний пустой элемент
		echo "Debng!";
		$this->requestAllInfo($this->users);
		echo "Debng!";
	}

	/**
	 * Функция из клиентской части
	 * 
	 * Формат исходного сообщения:
	 * Format: $OpList <nickname1>$$<nickname2>$$...$$<nicknameN>$$
	 *
	 * @param array $params
	 */
	protected function commandOpList($params,$rawmessage){
		$this->ops = explode("$$",$rawmessage);
		array_pop($this->ops);
		$this->requestAllInfo($this->ops);
	}

	/**
	 * Функция из клиентской части
	 * 
	 * Формат исходного сообщения:
	 * Format: $ForceMove <ipaddress>
	 *
	 * @param array $params
	 */
	protected function commandForceMove($params,$rawmessage){
		if(!$rawmessage){
			throw new Exception("Recieved kick signal from hub!");
		}
		$this->printToChat("Force-move command recieved to {$rawmessage}");
	}

	protected function commandMessage($params,$rawmessage){
		$this->printToChat($rawmessage);
	}

	public function __destruct(){
		parent::__destruct();
		echo "Destruct!";
	}
	
}

$dc = new DCClient("dc.airnet.lan");

$dc->debug = true;

$dc->sendMessage("Приветствую всех!");

$stdin = fopen("php://stdin","r");
stream_set_blocking($stdin,false);

$exit = true;

echo "Okey!\n";
while($exit){
	$dc->process();
	if($input = fgets($stdin)){
		@list($command,$op) = explode(" ",$input);
		echo $command;
		switch (trim($command)){
			case "/users":
				$dc->requestNickList();
				print_r($dc->users);
				break;
			case "/ops":
				$dc->requestNickList();
				print_r($dc->ops);
				break;
			case "/userinfo":
				$dc->requestUserInfo(trim($op));
				print_r($dc->collected_info[trim($op)]);
				break;	
			case "/exit":
				$exit = false;
				break;		
			default:
				$dc->sendMessage(trim($input));
		}
	}
	echo "loop!";
}

fclose($in);
echo "[END OF SCRIPT]\n";
?>
Внезапно умирает на вызове DC::requestAllInfo (а точнее он отрабатывает почти все но примерно в конце массива умирает при вызове метода DC::sendCommand() а точнее после вызова printDebugMsg())
 
Статус
В этой теме нельзя размещать новые ответы.
Сверху