* @version 0.0.0 * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2012 Hub Developer Team * @license GNU GPL 3.0 or any newer version * @link http://www.ship-simu.org * * 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 3 of the License, or * (at your option) 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, see . */ class TcpRawDataHandler extends BaseRawDataHandler implements Networkable { /** * Protected constructor * * @return void */ protected function __construct () { // Call parent constructor parent::__construct(__CLASS__); // Set handler name $this->setHandlerName('tcp'); } /** * Creates an instance of this class * * @return $handlerInstance An instance of a Networkable class */ public static final function createTcpRawDataHandler () { // Get new instance $handlerInstance = new TcpRawDataHandler(); // Return the prepared instance return $handlerInstance; } /** * Processes raw data from given resource. This is mostly useful for TCP * package handling and is implemented in the TcpListener class * * @param $resource A valid socket resource array * @return void */ public function processRawDataFromResource (array $socketArray) { // Check the resource if ((!isset($socketArray[BasePool::SOCKET_ARRAY_RESOURCE])) || (!is_resource($socketArray[BasePool::SOCKET_ARRAY_RESOURCE]))) { // Throw an exception throw new InvalidResourceException($this, self::EXCEPTION_INVALID_RESOURCE); } // END - if // Reset error code to unhandled $this->setErrorCode(self::SOCKET_ERROR_UNHANDLED); // Init variables $decodedData = false; // Debug message /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('TCP-HANDLER: Handling TCP package from resource=' . $socketArray[BasePool::SOCKET_ARRAY_RESOURCE] . ',type=' . $socketArray[BasePool::SOCKET_ARRAY_CONN_TYPE] . ',last error=' . socket_strerror(socket_last_error($socketArray[BasePool::SOCKET_ARRAY_RESOURCE]))); /* * Read the raw data from socket. If you change PHP_BINARY_READ to * PHP_NORMAL_READ, this line will endless block. This script does only * provide simultanous threads, not real. */ $rawData = socket_read($socketArray[BasePool::SOCKET_ARRAY_RESOURCE], $this->getConfigInstance()->getConfigEntry('tcp_buffer_length'), PHP_BINARY_READ); // Debug output of read data length /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('TCP-HANDLER: rawData[' . gettype($rawData) . ']=' . strlen($rawData) . ',MD5=' . md5($rawData) . ',resource=' . $socketArray[BasePool::SOCKET_ARRAY_RESOURCE] . ',error=' . socket_strerror(socket_last_error($socketArray[BasePool::SOCKET_ARRAY_RESOURCE]))); /* NOISY-DEBUG: */ if ($rawData !== false) self::createDebugInstance(__CLASS__)->debugOutput('TCP-HANDLER: rawData=' . $rawData); // Is it valid? if (socket_last_error($socketArray[BasePool::SOCKET_ARRAY_RESOURCE]) == 11) { // Debug message //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('TCP-HANDLER: Ignoring error 11 (Resource temporary unavailable) from socket resource=' . $socketArray[BasePool::SOCKET_ARRAY_RESOURCE]); /* * Error code 11 (Resource temporary unavailable) can be safely * ignored on non-blocking sockets. The socket is currently not * sending any data. */ socket_clear_error($socketArray[BasePool::SOCKET_ARRAY_RESOURCE]); // Skip any further processing return; } elseif (($rawData === false) || (socket_last_error($socketArray[BasePool::SOCKET_ARRAY_RESOURCE]) > 0)) { // Network error or connection lost $this->setErrorCode(socket_last_error($socketArray[BasePool::SOCKET_ARRAY_RESOURCE])); } elseif (empty($rawData)) { // The peer did send nothing to us which is now being ignored return; } else { /* * Low-level checks of the raw data went all fine, now decode the * raw data. This may still fail because of invalid encoded data. */ $decodedData = $this->getInputStreamInstance()->streamData($rawData); } // Add the (maybe above decoded) data to the stacker $this->addDecodedDataToStacker($decodedData); } } // [EOF] ?>