]> git.mxchange.org Git - hub.git/commitdiff
Now incoming, outgoing and 'server' pools are possible
authorRoland Häder <roland@mxchange.org>
Sat, 19 May 2012 16:29:13 +0000 (16:29 +0000)
committerRoland Häder <roland@mxchange.org>
Sat, 19 May 2012 16:29:13 +0000 (16:29 +0000)
16 files changed:
.gitattributes
application/hub/exceptions/connection/.htaccess [new file with mode: 0644]
application/hub/exceptions/connection/class_InvalidConnectionTypeException.php [new file with mode: 0644]
application/hub/interfaces/discovery/class_DiscoverableSocket.php
application/hub/interfaces/handler/network/class_Networkable.php
application/hub/interfaces/pool/peer/class_PoolablePeer.php
application/hub/interfaces/socket/class_SocketTag.php
application/hub/main/class_BaseHubSystem.php
application/hub/main/discovery/socket/class_PackageSocketDiscovery.php
application/hub/main/handler/network/tcp/class_TcpRawDataHandler.php
application/hub/main/handler/network/udp/class_UdpRawDataHandler.php
application/hub/main/helper/connection/class_BaseConnectionHelper.php
application/hub/main/listener/tcp/class_TcpListener.php
application/hub/main/package/class_NetworkPackage.php
application/hub/main/pools/class_BasePool.php
application/hub/main/pools/peer/class_DefaultPeerPool.php

index efafc998dd1218f0a116eaacee529913514cee27..ffa130e516f138fe1c37f4244914219d179d2e97 100644 (file)
@@ -10,6 +10,8 @@ application/hub/exceptions.php svneol=native#text/plain
 application/hub/exceptions/.htaccess -text svneol=unset#text/plain
 application/hub/exceptions/announcement/.htaccess -text svneol=unset#text/plain
 application/hub/exceptions/announcement/class_AnnouncementNotAcceptedException.php svneol=native#text/plain
+application/hub/exceptions/connection/.htaccess -text svneol=unset#text/plain
+application/hub/exceptions/connection/class_InvalidConnectionTypeException.php svneol=native#text/plain
 application/hub/exceptions/hub/.htaccess -text svneol=unset#text/plain
 application/hub/exceptions/hub/class_HubAlreadyAnnouncedException.php svneol=native#text/plain
 application/hub/exceptions/ids/.htaccess -text svneol=unset#text/plain
diff --git a/application/hub/exceptions/connection/.htaccess b/application/hub/exceptions/connection/.htaccess
new file mode 100644 (file)
index 0000000..3a42882
--- /dev/null
@@ -0,0 +1 @@
+Deny from all
diff --git a/application/hub/exceptions/connection/class_InvalidConnectionTypeException.php b/application/hub/exceptions/connection/class_InvalidConnectionTypeException.php
new file mode 100644 (file)
index 0000000..1c508bd
--- /dev/null
@@ -0,0 +1,46 @@
+<?php
+/**
+ * This exception is thrown when an invalid connection type is being detected
+ *
+ * @author             Roland Haeder <webmaster@ship-simu.org>
+ * @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 <http://www.gnu.org/licenses/>.
+ */
+class InvalidConnectionTypeException extends FrameworkException {
+       /**
+        * The super constructor for all exceptions
+        *
+        * @param       $messageArray   Error message array
+        * @param       $code                   Error code
+        * @return      void
+        */
+       public function __construct (array $messageArray, $code) {
+               // Construct the message
+               $message = sprintf("[%s:%d] Connection type %s is invalid.",
+                       $messageArray[0]->__toString(),
+                       $this->getLine(),
+                       $messageArray[1]
+               );
+
+               // Call parent exception constructor
+               parent::__construct($message, $code);
+       }
+}
+
+// [EOF]
+?>
index dbc284efec1152d668d039fd87ca9967e5aaa736..cf57357a2d47bfa4c40d5630e4269d2cc0f9991b 100644 (file)
@@ -27,10 +27,12 @@ interface DiscoverableSocket extends FrameworkInterface {
         * matching socket resource.
         *
         * @param       $packageData            Raw package data array
-        * @param       $packageInstance        A Deliverable instance
+        * @param       $connectionType         Type of connection, can be 'incoming' or 'outgoing', *NEVER* 'server'!
         * @return      $socketResource         A valid socket resource
+        * @throws      NoListGroupException    If the procol group is not found in peer list
+        * @throws      NullPointerException    If listenerInstance is NULL
         */
-       function discoverSocket (array $packageData);
+       function discoverSocket (array $packageData, $connectionType);
 }
 
 // [EOF]
index 03c52512b4f8ef810df2894e5756f8e9e5846b3d..9788a8a4c2055c84163c47a566a10e810b0f93da 100644 (file)
@@ -26,11 +26,11 @@ interface Networkable extends Handleable {
         * 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 resource identifier
+        * @param       $resourceArray  A valid socket resource array
         * @return      void
         * @throws      InvalidResourceException        If the given resource is invalid
         */
-       function processRawDataFromResource ($resource);
+       function processRawDataFromResource (array $resourceArray);
 
        /**
         * Checks whether decoded data is pending for further processing.
index b33fa5adf8044cf10eb11ef91d3a640f3c1fa1de..769a13edc30dce8a6ff83b17966c440a930b8ebf 100644 (file)
@@ -26,9 +26,33 @@ interface PoolablePeer extends Poolable, SocketTag {
         * Adds a socket resource to the peer pool
         *
         * @param       $socketResource         A valid (must be!) socket resource
+        * @param       $connectionType         Type of connection, can only be 'incoming', 'outgoing' or 'server'
         * @return      void
+        * @throws      InvalidSocketException  If the given resource is invalid or errorous
         */
-       function addPeer ($socketResource);
+       function addPeer ($socketResource, $connectionType);
+
+       /**
+        * Getter for array of all socket resource arrays
+        *
+        * @return      $sockets        An array with all socket arrays
+        */
+       function getAllSockets ();
+
+       /**
+        * Getter for array of all socket resources
+        *
+        * @return      $sockets        An array with all sockets
+        */
+       function getAllSingleSockets ();
+
+       /**
+        * "Getter" for all sockets of specified type
+        *
+        * @param       $connectionType         Type of connection, can only be 'incoming', 'outgoing' or 'server'
+        * @return      $sockets                        An array with sockets of given type
+        */
+       function getSocketsByConnectionType ($connectionType);
 }
 
 // [EOF]
index b9a41d6d597dee50bdd7a571dd800bcc5275e52b..9e65c96c5ddf82ce7abb19b193d6fb4e12805fe0 100644 (file)
@@ -26,9 +26,11 @@ interface SocketTag extends FrameworkInterface {
         * "Getter" for a valid socket resource from given packae data.
         *
         * @param       $packageData            Raw package data
+        * @param       $connectionType         Type of connection, can be 'incoming', 'outgoing', 'server' or default
         * @return      $socketResource         Socket resource
+        * @throws      InvalidConnectionTypeException  If the provided connection type is not valid
         */
-       function getSocketFromPackageData (array $packageData);
+       function getSocketFromPackageData (array $packageData, $connectionType = NULL);
 }
 
 // [EOF]
index a607160265d2e98fc354d32e78a97b74c93a48bf..6a7ff2f1d85f1fb250311d7c9c449bf3488f1fd5 100644 (file)
@@ -26,6 +26,7 @@ class BaseHubSystem extends BaseFrameworkSystem {
        const EXCEPTION_UNSUPPORTED_ERROR_HANDLER = 0x900;
        const EXCEPTION_CHUNK_ALREADY_ASSEMBLED   = 0x901;
        const EXCEPTION_ANNOUNCEMENT_NOT_ACCEPTED = 0x902;
+       const EXCEPTION_INVALID_CONNECTION_TYPE   = 0x903;
 
        // Message status codes
        const MESSAGE_STATUS_CODE_OKAY = 'OKAY';
index ef20e5c3acacf416f9ffbfd0fb1dd7329e17225f..9aea31d0056173213fc322be00822eea2e1018da 100644 (file)
@@ -97,11 +97,15 @@ class PackageSocketDiscovery extends BaseHubDiscovery implements DiscoverableSoc
         * matching socket resource for that protocol.
         *
         * @param       $packageData            Raw package data array
+        * @param       $connectionType         Type of connection, can be 'incoming' or 'outgoing', *NEVER* 'server'!
         * @return      $socketResource         A valid socket resource or FALSE if an error occured
         * @throws      NoListGroupException    If the procol group is not found in peer list
         * @throws      NullPointerException    If listenerInstance is NULL
         */
-       public function discoverSocket (array $packageData) {
+       public function discoverSocket (array $packageData, $connectionType) {
+               // Assert on type
+               assert($connectionType != BaseConnectionHelper::CONNECTION_TYPE_SERVER);
+
                // Determine protocol name
                $protocolName = $this->determineProtocolByPackageData($packageData);
 
@@ -126,7 +130,7 @@ class PackageSocketDiscovery extends BaseHubDiscovery implements DiscoverableSoc
                 * instance and pass over the whole package data to get the right
                 * socket.
                 */
-               $socketResource = $listenerInstance->getPoolInstance()->getSocketFromPackageData($packageData);
+               $socketResource = $listenerInstance->getPoolInstance()->getSocketFromPackageData($packageData, $connectionType);
 
                // Debug message
                if (is_resource($socketResource)) {
index 304c9775a55ea1aef5cf249db93672f27869f2c3..e71b3f1511309f7a305c15f213fe18dc242aa106 100644 (file)
@@ -52,12 +52,12 @@ class TcpRawDataHandler extends BaseRawDataHandler implements Networkable {
         * 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 resource identifier
+        * @param       $resource       A valid socket resource array
         * @return      void
         */
-       public function processRawDataFromResource ($resource) {
+       public function processRawDataFromResource (array $socketArray) {
                // Check the resource
-               if (!is_resource($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
@@ -69,32 +69,32 @@ class TcpRawDataHandler extends BaseRawDataHandler implements Networkable {
                $decodedData = false;
 
                // Debug message
-               /* NOISY-DEBUG: */ $this->debugOutput('TCP-HANDLER: Handling TCP package from peer ' . $resource . ',last error=' . socket_strerror(socket_last_error($resource)));
+               /* NOISY-DEBUG: */ $this->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($resource, $this->getConfigInstance()->getConfigEntry('tcp_buffer_length'), PHP_BINARY_READ);
+               $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: */ $this->debugOutput('TCP-HANDLER: rawData[' . gettype($rawData) . ']=' . strlen($rawData) . ',resource=' . $resource . ',error=' . socket_strerror(socket_last_error($resource)));
+               /* NOISY-DEBUG: */ $this->debugOutput('TCP-HANDLER: rawData[' . gettype($rawData) . ']=' . strlen($rawData) . ',resource=' . $socketArray[BasePool::SOCKET_ARRAY_RESOURCE] . ',error=' . socket_strerror(socket_last_error($socketArray[BasePool::SOCKET_ARRAY_RESOURCE])));
 
                // Is it valid?
-               if (socket_last_error($resource) == 11) {
+               if (socket_last_error($socketArray[BasePool::SOCKET_ARRAY_RESOURCE]) == 11) {
                        // Debug message
-                       /* NOISY-DEBUG: */ $this->debugOutput('TCP-HANDLER: Ignoring error 11 (Resource temporary unavailable) from socket resource=' . $resource);
+                       /* NOISY-DEBUG: */ $this->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($resource);
-               } elseif (($rawData === false) || (socket_last_error($resource) > 0)) {
+                        socket_clear_error($socketArray[BasePool::SOCKET_ARRAY_RESOURCE]);
+               } elseif (($rawData === false) || (socket_last_error($socketArray[BasePool::SOCKET_ARRAY_RESOURCE]) > 0)) {
                        // Network error or connection lost
-                       $this->setErrorCode(socket_last_error($resource));
+                       $this->setErrorCode(socket_last_error($socketArray[BasePool::SOCKET_ARRAY_RESOURCE]));
                } elseif (empty($rawData)) {
                        // The peer did send nothing to us
                        $this->setErrorCode(self::SOCKET_ERROR_EMPTY_DATA);
index ec067ebd3a04180cb90da593258046e0b10679e8..703a5502fe68d41b0a82acf1e1e6a5a1077893c1 100644 (file)
@@ -52,20 +52,20 @@ class UdpRawDataHandler extends BaseRawDataHandler implements Networkable {
         * 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 resource identifier
+        * @param       $socketArray    A valid socket resource array
         * @return      void
         * @throws      InvalidResourceException        If the given resource is invalid
         * @todo        0%
         */
-       public function processRawDataFromResource ($resource) {
+       public function processRawDataFromResource (array $socketArray) {
                // Check the resource
-               if (!is_resource($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
 
                // Implement processing here
-               $this->partialStub('Please implement this method. resource=' . $resource);
+               $this->partialStub('Please implement this method. resource=' . $socketArray[BasePool::SOCKET_ARRAY_RESOURCE] . ',type=' . $socketArray[BasePool::SOCKET_ARRRAY_CONN_TYPE]);
        }
 }
 
index c6f5ceef4003aadb63c410b27d76fcdcaacd39b5..c13e74d356291f8bd0af41ae4f2e041e6a1e606e 100644 (file)
@@ -25,6 +25,21 @@ class BaseConnectionHelper extends BaseHubHelper implements Registerable, Protoc
        // Exception codes
        const EXCEPTION_UNSUPPORTED_ERROR_HANDLER = 0x900;
 
+       /**
+        * Connection type 'incoming'
+        */
+       const CONNECTION_TYPE_INCOMING = 'incoming';
+
+       /**
+        * Connection type 'outgoing'
+        */
+       const CONNECTION_TYPE_OUTGOING = 'outgoing';
+
+       /**
+        * Connection type 'server'
+        */
+       const CONNECTION_TYPE_SERVER   = 'server';
+
        /**
         * Protocol used
         */
index 0ad6eccd683f41c5609329fbdcbfe478c35dab97..00f78b185df32b4223734a4d9ad8bda2812e7bc8 100644 (file)
@@ -171,7 +171,7 @@ class TcpListener extends BaseListener implements Listenable {
                $poolInstance = ObjectFactory::createObjectByConfiguredName('node_pool_class', array($this));
 
                // Add main socket
-               $poolInstance->addPeer($mainSocket);
+               $poolInstance->addPeer($mainSocket, BaseConnectionHelper::CONNECTION_TYPE_SERVER);
 
                // And add it to this listener
                $this->setPoolInstance($poolInstance);
@@ -201,7 +201,7 @@ class TcpListener extends BaseListener implements Listenable {
         */
        public function doListen () {
                // Get all readers
-               $readers = $this->getPoolInstance()->getAllSockets();
+               $readers = $this->getPoolInstance()->getAllSingleSockets();
                $writers = array();
                $excepts = array();
 
@@ -232,7 +232,7 @@ class TcpListener extends BaseListener implements Listenable {
                        $newSocket = socket_accept($this->getSocketResource());
 
                        // Debug message
-                       /* NOISY-DEBUG: */ $this->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: newSocket=' . $newSocket . ',server=' .$this->getSocketResource());
+                       //* NOISY-DEBUG: */ $this->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']: newSocket=' . $newSocket . ',server=' .$this->getSocketResource());
 
                        // Array for timeout settings
                        $options  = array(
@@ -268,7 +268,7 @@ class TcpListener extends BaseListener implements Listenable {
                        } // END - if
 
                        // Add it to the peers
-                       $this->getPoolInstance()->addPeer($newSocket);
+                       $this->getPoolInstance()->addPeer($newSocket, BaseConnectionHelper::CONNECTION_TYPE_INCOMING);
 
                        // Get peer name
                        if (!socket_getpeername($newSocket, $peerName)) {
@@ -301,7 +301,7 @@ class TcpListener extends BaseListener implements Listenable {
                $currentSocket = $this->getIteratorInstance()->current();
 
                // Handle it here, if not main socket
-               /* NOISY-DEBUG: */ $this->debugOutput('TCP-LISTENER: currentSocket=' . $currentSocket . ',server=' . $this->getSocketResource());
+               /* NOISY-DEBUG: */ $this->debugOutput('TCP-LISTENER: currentSocket=' . $currentSocket[BasePool::SOCKET_ARRAY_RESOURCE] . ',type=' . $currentSocket[BasePool::SOCKET_ARRAY_CONN_TYPE] . ',server=' . $this->getSocketResource());
                if ($currentSocket != $this->getSocketResource()) {
                        // ... or else it will raise warnings like 'Transport endpoint is not connected'
                        $this->getHandlerInstance()->processRawDataFromResource($currentSocket);
index 9fa8cdd6725bf7c431e651a32c40259d434763a9..b57155abaf1c1b0d03f462a27f9fb3d2dba9c512 100644 (file)
@@ -463,7 +463,7 @@ class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, R
                $discoveryInstance = SocketDiscoveryFactory::createSocketDiscoveryInstance();
 
                // Now discover the right protocol
-               $socketResource = $discoveryInstance->discoverSocket($packageData);
+               $socketResource = $discoveryInstance->discoverSocket($packageData, BaseConnectionHelper::CONNECTION_TYPE_OUTGOING);
 
                // Debug message
                //* NOISY-DEBUG: */ $this->debugOutput('NETWORK-PACKAGE: Reached line ' . __LINE__ . ' after discoverSocket() has been called.');
index b15cfd2641cd7977727d71322a78bae5e742e528..ca2243d4913ccae0c7a24de9f307cdfd3af455ec 100644 (file)
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 class BasePool extends BaseHubSystem implements Visitable {
+       /**
+        * Socket array elements
+        */
+       const SOCKET_ARRAY_RESOURCE  = 'resource';
+       const SOCKET_ARRAY_CONN_TYPE = 'connection_type';
+
        /**
         * A list of pool entries
         */
        private $poolEntriesInstance = NULL;
 
+       /**
+        * An array with all valid connection types
+        */
+       private $connectionTypes = array();
+
        /**
         * Protected constructor
         *
@@ -39,6 +50,13 @@ class BasePool extends BaseHubSystem implements Visitable {
 
                // Init the pool entries
                $this->poolEntriesInstance = ObjectFactory::createObjectByConfiguredName('pool_entries_list_class');
+
+               // Init array of connection types
+               $this->connectionTypes = array(
+                       BaseConnectionHelper::CONNECTION_TYPE_INCOMING,
+                       BaseConnectionHelper::CONNECTION_TYPE_OUTGOING,
+                       BaseConnectionHelper::CONNECTION_TYPE_SERVER
+               );
        }
 
        /**
@@ -143,6 +161,20 @@ class BasePool extends BaseHubSystem implements Visitable {
                // Return it
                return $array;
        }
+
+       /**
+        * Checks whether the given connection type is valid
+        *
+        * @param       $connectionType         Type of connection, can be 'incoming', 'outgoing' or 'server'
+        * @return      $isValid                        Whether the provided connection type is valid
+        */
+       protected function isValidConnectionType ($connectionType) {
+               // Is it valid?
+               $isValid = in_array($connectionType, $this->connectionTypes, true);
+
+               // Return result
+               return $isValid;
+       }
 }
 
 // [EOF]
index 7d0a92ceeeb54b0cc4bd49fcfe96db2a8f91d2a4..b0d7621612f7e869b6e09a18740c58b35fffc0ec 100644 (file)
@@ -87,10 +87,11 @@ class DefaultPeerPool extends BasePool implements PoolablePeer {
         * Adds a socket resource to the peer pool
         *
         * @param       $socketResource         A valid (must be!) socket resource
+        * @param       $connectionType         Type of connection, can only be 'incoming', 'outgoing' or 'server'
         * @return      void
         * @throws      InvalidSocketException  If the given resource is invalid or errorous
         */
-       public function addPeer ($socketResource) {
+       public function addPeer ($socketResource, $connectionType) {
                // Validate the socket
                $this->validateSocket($socketResource);
 
@@ -119,8 +120,14 @@ class DefaultPeerPool extends BasePool implements PoolablePeer {
                // Debug message
                $this->debugOutput('POOL: Adding peer ' . $peerName . ',socketResource=' . $socketResource);
 
+               // Construct the array
+               $socketArray = array(
+                       self::SOCKET_ARRAY_RESOURCE  => $socketResource,
+                       self::SOCKET_ARRAY_CONN_TYPE => $connectionType
+               );
+
                // Add it finally to the pool
-               $this->addPoolEntry($socketResource);
+               $this->addPoolEntry($socketArray);
        }
 
        /**
@@ -136,13 +143,63 @@ class DefaultPeerPool extends BasePool implements PoolablePeer {
                return $sockets;
        }
 
+       /**
+        * Getter for array of all socket arrays
+        *
+        * @return      $sockets        An array with all socket arrays
+        */
+       public final function getAllSingleSockets () {
+               // Get the array list
+               $socketArrays = $this->getArrayFromList('pool');
+
+               // Init socket array
+               $sockets = array();
+
+               // "Walk" through all socket arrays
+               foreach ($socketArrays as $socketArray) {
+                       // Add the socket
+                       $sockets[] = $socketArray[self::SOCKET_ARRAY_RESOURCE];
+               } // END - foreach
+
+               // Return it
+               return $sockets;
+       }
+
+       /**
+        * "Getter" for all sockets of specified type
+        *
+        * @param       $connectionType         Type of connection, can only be 'incoming', 'outgoing' or 'server'
+        * @return      $sockets                        An array with sockets of given type
+        */
+       public function getSocketsByConnectionType ($connectionType) {
+               // Get the array list
+               $socketArrays = $this->getArrayFromList('pool');
+
+               // Init socket array
+               $sockets = array();
+
+               // "Walk" through all socket arrays
+               foreach ($socketArrays as $socketArray) {
+                       // Does it match?
+                       if ($socketArray[self::SOCKET_ARRAY_CONN_TYPE] === $connectionType) {
+                               // Add the socket
+                               $sockets[] = $socketArray[self::SOCKET_ARRAY_RESOURCE];
+                       } // END - if
+               } // END - foreach
+
+               // Return it
+               return $sockets;
+       }
+
        /**
         * "Getter" for a valid socket resource from given packae data.
         *
         * @param       $packageData            Raw package data
+        * @param       $connectionType         Type of connection, can be 'incoming', 'outgoing', 'server' or default
         * @return      $socketResource         Socket resource
+        * @throws      InvalidConnectionTypeException  If the provided connection type is not valid
         */
-       public function getSocketFromPackageData (array $packageData) {
+       public function getSocketFromPackageData (array $packageData, $connectionType = NULL) {
                // Default is no socket
                $socketResource = false;
 
@@ -155,29 +212,41 @@ class DefaultPeerPool extends BasePool implements PoolablePeer {
                // Debug message
                /* NOISY-DEBUG: */ $this->debugOutput('POOL: Checking ' . count($this->getAllSockets()) . ' socket(s),recipientIpArray[0]=' . $recipientIpArray[0] . ',recipientIpArray[1]=' . $recipientIpArray[1] . ' ...');
 
+               // Default is all sockets
+               $sockets = $this->getAllSockets();
+
+               // Is connection type set?
+               if ((is_string($connectionType)) && ($this->isValidConnectionType($connectionType))) {
+                       // Then get a list of this type
+                       $sockets = $this->getSocketsByConnectionType($connectionType);
+               } elseif (is_string($connectionType)) {
+                       // Is not a valid connection type!
+                       throw new InvalidConnectionTypeException(array($this, $connectionType), self::EXCEPTION_INVALID_CONNECTION_TYPE);
+               }
+
                // Get all sockets and check them, skip the server socket
-               foreach ($this->getAllSockets() as $socket) {
+               foreach ($sockets as $socketArray) {
                        // Is this a server socket?
-                       if ($socket === $this->getListenerInstance()->getSocketResource()) {
+                       if ($socketArray[self::SOCKET_ARRAY_RESOURCE] === $this->getListenerInstance()->getSocketResource()) {
                                // Skip 'server' sockets (local socket)
-                               /* NOISY-DEBUG: */ $this->debugOutput('POOL: Skipping server socket ' . $socket . ' ...');
+                               /* NOISY-DEBUG: */ $this->debugOutput('POOL: Skipping server socket ' . $socketArray[self::SOCKET_ARRAY_RESOURCE] . ' ...');
                                continue;
                        } // END - if
 
                        // Try to get the "peer"'s name
-                       if (!socket_getpeername($socket, $peerIp)) {
+                       if (!socket_getpeername($socketArray[self::SOCKET_ARRAY_RESOURCE], $peerIp)) {
                                // Handle the socket error with given package data
-                               $this->handleSocketError(__METHOD__, __LINE__, $socket, explode(':', $packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT]));
+                               $this->handleSocketError(__METHOD__, __LINE__, $socketArray[self::SOCKET_ARRAY_RESOURCE], explode(':', $packageData[NetworkPackage::PACKAGE_DATA_RECIPIENT]));
                        } // END - if
 
                        // Get
                        // If the "peer" IP and recipient is same, use it
                        if ($peerIp == $recipientIpArray[0]) {
                                // IPs match, so take the socket and quit this loop
-                               $socketResource = $socket;
+                               $socketResource = $socketArray[self::SOCKET_ARRAY_RESOURCE];
 
                                // Debug message
-                               /* NOISY-DEBUG: */ $this->debugOutput('POOL: peerIp=' . $peerIp . ' matches with recipient IP address. Taking socket=' . $socket);
+                               /* NOISY-DEBUG: */ $this->debugOutput('POOL: peerIp=' . $peerIp . ' matches with recipient IP address. Taking socket=' . $socketArray[self::SOCKET_ARRAY_RESOURCE] . ',type=' . $socketArray[self::SOCKET_ARRAY_CONN_TYPE]);
                                break;
                        } // END - if
                } // END - foreach