Beispiel #1
0
 def __init__(self, isServer, ipAddr, port, factory, queue,
              incomingDataThread, callbackObject):
     """
     Initializes the connection.
     Args:
         isServer: True when this is a server connection or False otherwise.
         ipAddr: the server's IP address
         port: the port assigned to the connection.  
         factory: the protocol factory assigned to the connnection     
         queue: the incoming data queue assigned to the connection
         incomingDataThread: the incoming data thread assigned to the connection
         callbackObject: the callback object assigned to the connection     
     """
     self.__status = _ConnectionStatus(CONNECTION_STATUS.OPENING)
     self.__isServer = isServer
     self.__ipAddr = ipAddr
     self.__port = port
     self.__factory = factory
     self.__queue = queue
     self.__incomingDataThread = incomingDataThread
     self.__callback = callbackObject
     self.__packagesToSend = MultithreadingCounter()
     self.__deferred = None
     self.__listeningPort = None
     self.__unexpectedlyClosed = False
     self.__error = None
 def __init__(self, queue, callbackObject):
     """
     Initializes the thread's state
     Args:
         queue: The incoming packages queue 
         callbackObject: The callback object that will process
         all the received packets.
     """
     QueueProcessingThread.__init__(self, "Incoming data processing thread",
                                    queue)
     self.__callbackObject = callbackObject
     self.__referenceCounter = MultithreadingCounter()
 def __init__(self, queue, callbackObject):
     """
     Initializes the thread's state
     Args:
         queue: The incoming packages queue 
         callbackObject: The callback object that will process
         all the received packets.
     """
     QueueProcessingThread.__init__(self, "Incoming data processing thread", queue)   
     self.__callbackObject = callbackObject     
     self.__referenceCounter = MultithreadingCounter()
class _IncomingDataThread(QueueProcessingThread):
    """
    Incoming packages thread class.
    This threads will process the incoming packages.
    """
    def __init__(self, queue, callbackObject):
        """
        Initializes the thread's state
        Args:
            queue: The incoming packages queue 
            callbackObject: The callback object that will process
            all the received packets.
        """
        QueueProcessingThread.__init__(self, "Incoming data processing thread",
                                       queue)
        self.__callbackObject = callbackObject
        self.__referenceCounter = MultithreadingCounter()

    def start(self):
        """
        Starts the thread
        Args:
            None
        Returns:
            Nothing
        """
        self.__referenceCounter.increment()
        if (self.__referenceCounter.read() == 1):
            QueueProcessingThread.start(self)

    def stop(self, join):
        """
        Asks this thread to terminate.
        Args:
            join: When True, the calling thread will wait the incoming data thread
            to terminate. When False, the calling thread will only ask this thread to terminate.
        Returns: 
            Nothing
        """
        self.__referenceCounter.decrement()
        if self.__referenceCounter.read() == 0:
            QueueProcessingThread.stop(self)
            if join:
                self.join()

    def run(self):
        QueueProcessingThread.run(self)

    def processElement(self, e):
        """
        Processes a received packet
        Args:
            e: The packet to process
        Returns:
            Nothing
        """
        self.__callbackObject.processPacket(e)
class _IncomingDataThread(QueueProcessingThread):
    """
    Incoming packages thread class.
    This threads will process the incoming packages.
    """
    def __init__(self, queue, callbackObject):
        """
        Initializes the thread's state
        Args:
            queue: The incoming packages queue 
            callbackObject: The callback object that will process
            all the received packets.
        """
        QueueProcessingThread.__init__(self, "Incoming data processing thread", queue)   
        self.__callbackObject = callbackObject     
        self.__referenceCounter = MultithreadingCounter()
        
    def start(self):
        """
        Starts the thread
        Args:
            None
        Returns:
            Nothing
        """
        self.__referenceCounter.increment()
        if (self.__referenceCounter.read() == 1) :
            QueueProcessingThread.start(self)
        
    def stop(self, join):
        """
        Asks this thread to terminate.
        Args:
            join: When True, the calling thread will wait the incoming data thread
            to terminate. When False, the calling thread will only ask this thread to terminate.
        Returns: 
            Nothing
        """
        self.__referenceCounter.decrement()
        if self.__referenceCounter.read() == 0 :
            QueueProcessingThread.stop(self)
            if join :
                self.join()
                
    def run(self):
        QueueProcessingThread.run(self)
        
    def processElement(self, e):
        """
        Processes a received packet
        Args:
            e: The packet to process
        Returns:
            Nothing
        """
        self.__callbackObject.processPacket(e)
Beispiel #6
0
class _NetworkConnection(object):
    """
    A class that represents a network connection.
    """
    def __init__(self, isServer, ipAddr, port, factory, queue,
                 incomingDataThread, callbackObject):
        """
        Initializes the connection.
        Args:
            isServer: True when this is a server connection or False otherwise.
            ipAddr: the server's IP address
            port: the port assigned to the connection.  
            factory: the protocol factory assigned to the connnection     
            queue: the incoming data queue assigned to the connection
            incomingDataThread: the incoming data thread assigned to the connection
            callbackObject: the callback object assigned to the connection     
        """
        self.__status = _ConnectionStatus(CONNECTION_STATUS.OPENING)
        self.__isServer = isServer
        self.__ipAddr = ipAddr
        self.__port = port
        self.__factory = factory
        self.__queue = queue
        self.__incomingDataThread = incomingDataThread
        self.__callback = callbackObject
        self.__packagesToSend = MultithreadingCounter()
        self.__deferred = None
        self.__listeningPort = None
        self.__unexpectedlyClosed = False
        self.__error = None

    def getIPAddress(self):
        """
        Returns the server's IP address
        Args:
            None
        Returns:
            The server's IP address. If this machine is a server, then 127.0.0.1
            will be returned.
        """
        return self.__ipAddr

    def getPort(self):
        """
        Returns the port assigned to this connection.
        Args:
            None
        Returns:
            The port assigned to this connection.
        """
        return self.__port

    def getQueue(self):
        """
        Returns the incoming data queue assigned to this connection.
        Args:
            None
        Returns:
            The incoming data queue assigned to this connection            
        """
        return self.__queue

    def getThread(self):
        """
        Returns the incoming data processing thread assigned to this connection
        Args:
            None
        Returns:
            The incoming data processing thread assigned to this connection
        """
        return self.__incomingDataThread

    def getCallback(self):
        """
        Returns the callback object assigned to this connection
        Args:
            None
        Returns:
            The callback object assigned to this connection.
        """
        return self.__callback

    def getStatus(self):
        """
        Returns the connection status
        Args:
            None
        Returns:
            The connection status
        """
        return self.__status.get()

    def sendPacket(self, p):
        """
        Sends a packet though this connection. If the connection is closed, the packet will be discarded.
        Args:
            p: the packet to send
        Returns:
            None
        """
        if (self.__status == CONNECTION_STATUS.CLOSED):
            # No packets will be sent though a closed connection.
            return
        self.__factory.sendPacket(p)
        self.__packagesToSend.decrement()

    def registerPacket(self):
        """
        Registers a packet to be sent through this connection.
        Args:
            None
        Returns:
            Nothing
        """
        self.__packagesToSend.increment()

    def isReady(self):
        """
        Checks if the connection is ready to send data or not
        Args:
            None
        Returns:
            True if the connection is ready to send data, and false otherwise.
        """
        return self.__status.get() == CONNECTION_STATUS.READY

    def isServerConnection(self):
        return self.__isServer

    def refresh(self):
        """
        Updates the connection's status
        Args:
            None
        Returns:
            Nothing
        """
        if self.__status.get() == CONNECTION_STATUS.OPENING:
            if (not self.__factory.isDisconnected()):
                if (not self.__isServer):
                    # Client => we've got everything we need
                    self.__status.set(CONNECTION_STATUS.READY)
                elif (self.__listeningPort != None):
                    # Server => the connection must also have a listening port before
                    # it's ready.
                    self.__status.set(CONNECTION_STATUS.READY_WAIT)
                self.__incomingDataThread.start()

        if self.__status.get() == CONNECTION_STATUS.READY_WAIT:
            if not self.__factory.isDisconnected():
                self.__status.set(CONNECTION_STATUS.READY)

        if self.__status.get() == CONNECTION_STATUS.CLOSING:
            if (self.__packagesToSend.read() == 0):
                # We can close the connection now
                self.__close()

        # Check what's happened to the factory
        if self.__status.get(
        ) == CONNECTION_STATUS.READY and self.__factory.isDisconnected():
            # This connection must be closed *right* now
            self.__status.set(CONNECTION_STATUS.CLOSED)
            self.__unexpectedlyClosed = True
            self.__close()

    def setListeningPort(self, listeningPort):
        """
        Set the IListeningPort assigned to a server connection
        Args:
            ListeningPort: the IListeningPort assigned to this connection
        Returns:
            Nothing
        """
        self.__listeningPort = listeningPort

    def setDeferred(self, deferred):
        """
        Modifies the deferred object stored in this connection.
        Deferred objects are returned by twisted, and allow us to know when a server connection
        is ready.
        """
        self.__deferred = deferred

    def isInErrorState(self):
        """
        Checks if the connection is in an error state.
        """
        return self.__status.get() == CONNECTION_STATUS.ERROR

    def wasUnexpectedlyClosed(self):
        """
        Checks if the connection was unexpectedly closed. The connection may be closed unexpectedly
        in two different ways:
            1) All the clients disconnect from a server.
            2) A server disconnects from all its clients.
        """
        return self.__unexpectedlyClosed

    def getError(self):
        """
        Returns the error message stored in this connection.
        """
        return self.__error

    def setError(self, value):
        """
        Modifies the error message stored in this connection.
        """
        self.__status.set(CONNECTION_STATUS.ERROR)
        self.__error = value

    def close(self):
        """
        Asks this connection to close
        Args:
            None
        Returns:
            Nothing
        """
        self.__status.set(CONNECTION_STATUS.CLOSING)

    def __close(self):
        """
        Asks twisted to close this connection.
        """
        if self.__isServer:
            if self.__listeningPort is None:
                self.__deferred.cancel()
            else:
                if not self.__factory.isDisconnected():
                    self.__listeningPort.loseConnection()
        else:
            self.__factory.disconnect()
        # Free the connection resources
        self.__incomingDataThread.stop(True)
        self.__status.set(CONNECTION_STATUS.CLOSED)