我们遇到的问题不是获取客户端,而是检索Rndk
并在此时继续检索它检索新客户端的部分
$this->logger->log("server", "A new client (ID: {$arrPenguin['id']}) has connected from {$arrPenguin['ip']}", "blue");
因为你可以看到在成功获得客户端时应该显示的顶部。
此外,这里有处理它的函数
<?php
class ServerBase {
public $settings;
public $intServerId;
public $logger;
public $bubble_socket;
public $arrPenguins = array();
public $bubbler;
public function __construct($settings, $intServerId, $loggerObject) {
$this->settings = $settings;
$this->intServerId = $intServerId;
$this->logger = $loggerObject;
$this->bubbler = new bubbler($settings);
$this->status = true;
return true;
}
public function startLoginServer() {
$err = $this->bubbler->errors;
$this->bubble_socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die($err['SOCK_ERR1']);
socket_set_option($this->bubble_socket, SOL_SOCKET, SO_REUSEADDR, 1);
socket_set_nonblock($this->bubble_socket);
$status = socket_bind($this->bubble_socket, 0, @$this->settings['login_port']) or die($err['SOCK_ERR2']);
socket_listen($this->bubble_socket, 5);
usleep(0);
if($status && isset($this->settings['login_port'])) {
$this->logger->log("alert", "Server socket was opened! Listening on port {$this->settings['login_port']} in login mode... \n", "cyan");
} else {
$this->logger->log("error", $err['SOCK_ERR3'], "red");
$this->bubbler->abort();
}
return true;
}
public function runLoginServer() {
socket_listen($this->bubble_socket);
while($this->status != false) {
$this->listen();
}
}
public function listen() {
$read_bubble = array($this->bubble_socket);
$x = null;
socket_select($read_bubble, $x, $x, $x);
if(in_array($this->bubble_socket, $read_bubble)) {
$read_bubble[] = $this->newClient();
$this->bubbler->continueLoop();
}
foreach($this->arrPenguins as $id => $class) {
$sock = $this->getSockById($id);
@socket_recv($sock, $strData, 8192, 0);
if(isset($strData)) {
$this->handleSockData($strData, $id, $sock);
} else {
$this->removeClientById($id);
}
}
usleep(0);
}
private function getFirstCharacter($data) {
return substr($data, 0, 1);
}
private function checkBadPacket($data) {
$marker = false;
if(!isset($data) || $data == "" || $data == " ") {
$marker = true;
}
return $marker;
}
public function handleSockData($data, $id, $sock) {
$err = $this->bubbler->errors;
if(@isset($this->arrPenguins[$id])) {
$arrPenguin = array();
$arrPenguin['id'] = $id;
$arrPenguin['sock'] = $this->arrPenguins[$id]->sock;
$arrPenguin['ip'] = $this->arrPenguins[$id]->ip;
if($this->checkBadPacket($data)) {
$this->logger->log("server", "{$err['BAD_PKT1']} by {$arrPenguin['ip']}", "red");
$this->removeClientById($id);
}
$strFirstChar = $this->getFirstCharacter($data);
if($strFirstChar == "<") {
$this->handleXMLPacket($data, $id, $sock);
} elseif($strFirstChar == "%") {
$this->handleXTPacket($data, $id, $sock);
} else {
$this->logger->log("server", "{$err['BAD_PKT2']} by {$arrPenguin['ip']}", "red");
$this->removeClientById($id);
}
} else {
socket_close($sock);
}
return true;
}
public function handleXMLPacket($data, $id, $sock) {
$this->handleXMLData($data, $id, $sock);
}
public function handleXMLData($data, $id, $sock) {
$arrPenguin = array();
$arrPenguin['id'] = $id;
$arrPenguin['sock'] = $this->arrPenguins[$id]->sock;
$arrPenguin['ip'] = $this->arrPenguins[$id]->ip;
if(isset($arrPenguin['id'], $arrPenguin['sock'], $arrPenguin['ip'])) {
if($this->settings['development_mode']) {
$this->logger->log("received", $data, "purple");
} else {
return true;
}
$this->parseXMLData($data, $id, $sock);
} else {
return false;
}
}
public function parseXMLData($data, $id, $sock) {
$arrPenguin = array();
$arrPenguin['id'] = $id;
$arrPenguin['sock'] = $this->arrPenguins[$id]->sock;
$arrPenguin['ip'] = $this->arrPenguins[$id]->ip;
$arrPenguin['class'] = $this->arrPenguins[$id];
$objPenguin = $arrPenguin['class'];
if(isset($arrPenguin['id'], $arrPenguin['sock'], $arrPenguin['ip'])) {
if($this->checkBadPacket($data)) {
$this->logger->log("server", "{$err['BAD_PKT1']} by {$arrPenguin['ip']}", "red");
$this->removeClientById($id);
}
if(strpos($data, "<policy-file-request/>") !== false) {
$objPenguin->send("<cross-domain-policy><allow-access-from domain='*' to-ports='*' /></cross-domain-policy>");
$this->removeClientById($id);
}
if(strpos($data, "<msg t='sys'><body action='verChk' r='0'>") !== false) {
$objPenguin->send("<msg t='sys'><body action='apiOK' r='0'></body></msg>");
}
if(strpos($data, "<msg t='sys'><body action='rndK' r='-1'></body></msg>") !== false) {
$objPenguin->send($this->generateRndK($data, $id, $sock));
}
} else {
}
}
private function generateRndK($data, $id, $sock) {
$len = 0;
$string = "";
$charBin = array(
'A', 'B', 'C', 'D',
'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L',
'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T',
'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b',
'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j',
'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r',
's', 't', 'u', 'v',
'w', 'x', 'y', 'z',
'1', '2', '3', '4',
'5', '6', '7', '8',
'9', '10',
);
while(strlen($len) < 9) {
$string .= array_rand($charBin, 1);
}
$RndK = $string;
$RndKPacket = "<msg t='sys'><body action='rndK' r='-1'><k>" . $RndK . "</k></body></msg>";
return $RndKPacket;
}
private function escapePacket($data) {
$data .= chr(0);
return $data;
}
public function sendBySock($data, $sock){
$data = $this->escapePacket($data);
$len = socket_send($sock, $data, strlen($data), MSG_EOR);
if($this->settings['development_mode']) {
$this->logger->log("sent", $data, "green");
}
return true;
}
public function removeClientById($id) {
$err = $this->bubbler->errors;
if(@isset($this->arrPenguins[$id])) {
$this->logger->log("server", "Succesfully removed client #" . $id, "brown");
socket_close($this->arrPenguins[$id]->sock);
unset($this->arrPenguins[$id]);
} else {
$this->logger->log("server", $err['BAD_REMV_IP1'], "red");
}
}
public function getSockById($id) {
$penguin = $this->arrPenguins[$id];
if(isset($penguin->sock)) {
return $penguin->sock;
}
}
public function getIpBySock($sock) {
socket_getpeername($sock, $ip);
$ip = "98.54.215.54";
return $ip;
}
public function getUniqueClientId() {
$count = 0;
foreach($this->arrPenguins as $id => $a) {
$count++;
}
$count++;
if(!array_key_exists($count, $this->arrPenguins)) {
return $count;
} else {
return $count++;
}
}
public function newClient() {
$id = $this->getUniqueClientId();
$arrPenguin = array();
$arrPenguin['id'] = $id;
$arrPenguin['sock'] = socket_accept($this->bubble_socket);
$arrPenguin['ip'] = $this->getIpBySock($arrPenguin['sock']);
$this->logger->log("server", "A new client (ID: {$arrPenguin['id']}) has connected from {$arrPenguin['ip']}", "blue");
$this->arrPenguins[$arrPenguin['id']] = new Penguin($arrPenguin, $this->settings);
return $id;
}
}
?>
这很难解释,因为我不确定StackOverFlow上的任何人都知道Club Penguins协议。