Hi, ich bastel grad an einem Admin tool für ein Game.
Die Kommunikation mit dem Server des Spiels erfolgt über eine XML-RPC Schnittstelle. Mein Problem ist nun, dass ich zwar mit socket_rescv daten vom server empfange (nämlich den Handshake), danach aber nichts mit socket_send senden kann.
PHP sagt zwar immer
aber es kommt nichts an.
Ich habe bereits alle anderen Möglichkeiten ausgeschlossen. Es muss am PHP liegen.
Setze ich das ganze statt mit sockets über die stream-funktionen um, so funktioniert es tadellos.
Vielleicht könnt ihr ja den Fehler finden, ich suche nämlich schon seit 2 Stunden mit einem Freund und finde da nicht, warum das Gesendete nicht ankommt
Ich habe euch die entsprechende Stelle mit # markiert. (Diese Stelle ist da nur zum testen drin, hat also keine wirkliche Funktion, macht aber das Problem deutlich)
Falls jemand noch die Klasse Protocol sehen möchte (wegen extend) hier ist sie. Hier kann der Fehler jedoch NICHT liegen.
Die Kommunikation mit dem Server des Spiels erfolgt über eine XML-RPC Schnittstelle. Mein Problem ist nun, dass ich zwar mit socket_rescv daten vom server empfange (nämlich den Handshake), danach aber nichts mit socket_send senden kann.
PHP sagt zwar immer
Errorno: 0
Error: Der Vorgang wurde erfolgreich abgeschlossen.
Error: Der Vorgang wurde erfolgreich abgeschlossen.
Ich habe bereits alle anderen Möglichkeiten ausgeschlossen. Es muss am PHP liegen.
Setze ich das ganze statt mit sockets über die stream-funktionen um, so funktioniert es tadellos.
Vielleicht könnt ihr ja den Fehler finden, ich suche nämlich schon seit 2 Stunden mit einem Freund und finde da nicht, warum das Gesendete nicht ankommt
PHP-Code:
<?php
interface iServer {
public function __construct();
public function __destruct();
}
class Server extends Protocol implements iServer {
private $logbook;
private $socket;
private $domain;
private $type;
private $protocol;
private $lasterror;
private $strerror;
private $address;
private $port;
private $connection;
public function __construct() {
global $kernel;
Protocol::__construct();
$this->logbook = $kernel->load("Logbook");
$this->domain = AF_INET;
$this->type = SOCK_STREAM;
$this->protocol = SOL_TCP;
$this->address = "localhost";
$this->port = 5000;
$this->connection = null;
$this->_getConfig();
}
public function connect() {
$this->socket = @socket_create($this->domain, $this->type, $this->protocol);
if($this->socket === false) {
$this->_getErrors();
$this->logbook->log("se", "Could not create socket @ ".$this->lasterror.":".$this->strerror."!");
}
$this->logbook->log("s", "Successfully created socket!");
$this->connection = @socket_connect($this->socket, $this->address, $this->port);
if($this->connection === false) {
$this->_getErrors();
$this->logbook->log("se", "Could not connect socket to ".$this->address.":".$this->port." @ ".$this->lasterror.":".$this->strerror."!");
}
$this->logbook->log("s", "Successfully connected socket to ".$this->address.":".$this->port."!");
$this->_handshake();
################################################################################################
socket_send($this->socket, "blabla", 6, null);
$this->_getErrors();
echo $this->lasterror;
echo $this->strerror;
################################################################################################
}
private function _getConfig() {
$config = parse_ini_file(getcwd().DIRECTORY_SEPARATOR."config".DIRECTORY_SEPARATOR."server.ini");
foreach($config as $setting=>$value) {
$this->$setting = $value;
}
}
private function _getErrors() {
$this->lasterror = socket_last_error($this->socket);
$this->strerror = socket_strerror($this->lasterror);
}
private function _handshake() {
if(!@socket_recv($this->socket, $length, 4, null)) {
$this->_getErrors();
$this->logbook->log("s", "Receiving from socket failed @ ".$this->lasterror.":".$this->strerror."!");
}
$length = @ord($length);
if(!@socket_recv($this->socket, $handshake, $length, null)) {
$this->_getErrors();
$this->logbook->log("s", "Receiving from socket failed @ ".$this->lasterror.":".$this->strerror."!");
}
if($handshake !== "GBXRemote 2") {
$this->logbook->log("se", "Handshake failed! Obviously connected to wrong server!");
}
$this->logbook->log("s", "Handshake succeeded! Connected to Trackmania Server!");
}
public function __destruct() {
Protocol::__destruct();
socket_close($this->socket);
unset($this);
}
}
?>
Falls jemand noch die Klasse Protocol sehen möchte (wegen extend) hier ist sie. Hier kann der Fehler jedoch NICHT liegen.
PHP-Code:
<?php
interface iProtocol {
public function __construct();
public function p_method();
public function __destruct();
}
class Protocol implements iProtocol {
private $xml;
public function __construct() {
$this->xml = "";
}
public function p_method() {
$arguments = func_get_args();
$method = array_shift($arguments);
$this->xml = "<?xml version='1.0' encoding='UTF-8' ?>";
$this->xml .= "<methodCall>";
$this->xml .= "<methodName>";
$this->xml .= $method;
$this->xml .= "</methodName>";
$this->xml .= "<params>";
foreach($arguments as $argument) {
$this->xml .= "<param>";
$this->xml .= "<value>";
$this->xml .= $this->_input($argument);
$this->xml .= "</value>";
$this->xml .= "</param>";
}
$this->xml .= "</params>";
$this->xml .= "</methodCall>";
return $this->xml;
}
private function _input($argument) {
$type = $this->_getType($argument);
if($type == "boolean") {
return "<boolean>".(int)$argument."</boolean>";
}
if($type == "integer") {
return "<int>".$argument."</int>";
}
if($type == "double") {
return "<double>".$argument."</double>";
}
if($type == "string") {
return "<string>".htmlspecialchars($argument)."</string>";
}
if($type == "array") {
$return = "<array><data>";
foreach($argument as $element) {
$return .= "<value>".$this->_input($element)."</value>";
}
$return .= "</data></array>";
return $return;
}
$return = "<struct>";
foreach($argument as $key=>$element) {
$return .= "<member>";
$return .= "<name>".$key."</name>";
$return .= "<value>".$this->_input($element)."</value>";
$return .= "</member>";
}
$return .= "</struct>";
return $return;
}
private function _getType($argument) {
switch(gettype($argument)) {
case "boolean":
return "boolean";
break;
case "integer":
return "integer";
break;
case "double":
return "double";
break;
case "string":
return "string";
break;
case "array":
$struct = false;
foreach($argument as $key=>$value) {
if(is_int($key)) {
continue;
}
$struct = true;
break;
}
if($struct) {
return "struct";
}
return "array";
break;
}
}
public function __destruct() {
unset($this);
}
}
?>