kode
never knows best
Скрипт внезапно умирает.
Есть код (вобще это много файлов, но всё слил в один):
Внезапно умирает на вызове DC::requestAllInfo (а точнее он отрабатывает почти все но примерно в конце массива умирает при вызове метода DC::sendCommand() а точнее после вызова printDebugMsg())
Есть код (вобще это много файлов, но всё слил в один):
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";
?>