Exemple #1
0
class TransceiverAFTN:
    """
    When started, a subscriber AFTN will listen on a port (56550), whishing to be
    connected by the AFTN provider. If this does not happen rapidly enough (before 
    the timeout expires), the subscriber will try to connect (port 5160) to the 
    provider.
    """
    def __init__(self, sourlient):

        AFTNPaths.normalPaths(sourlient.name)
        PXPaths.normalPaths()
        self.sysman = SystemManager()                      # General system manager
        self.sourlient = sourlient                         # Sourlient (Source/Client) object containing configuration infos.

        self.logger = sourlient.logger                     # Logger object
        self.subscriber = sourlient.subscriber             # Determine if it will act like a subscriber or a provider(MHS)
        self.host = sourlient.host                         # Remote host (name or ip)
        self.portR = sourlient.portR                       # Receiving port
        self.portS = sourlient.portS                       # Sending port
        
        self.batch = sourlient.batch                       # Number of files we read in a pass (20)
        self.timeout = sourlient.timeout                   # Timeout time in seconds (default = 10 seconds)
        self.sleepBetweenConnect = int('10')               # Time (in seconds) between connection trials 
        self.slow = sourlient.slow                         # Sleeps are added when we want to be able to decrypt log entries
        self.igniter = None                                # Igniter object (link to pid)

        self.writePath = AFTNPaths.RECEIVED                # Where we write messages we receive
        self.archivePath = AFTNPaths.SENT                  # Where we put sent messages
        self.specialOrdersPath = AFTNPaths.SPECIAL_ORDERS  # Where we put special orders

        # Paths creation
        self.sysman.createDir(PXPaths.TXQ + self.sourlient.name)
        self.sysman.createDir(self.writePath)
        self.sysman.createDir(self.archivePath)
        self.sysman.createDir(self.specialOrdersPath)


        self.mm = MessageManager(self.logger, self.sourlient)  # AFTN Protocol is implemented in MessageManager Object
        self.remoteAddress = None                          # Remote address (where we will connect())
        self.socket = None                                 # Socket object
        self.dataFromFiles = []                            # A list of tuples (content, filename) obtained from a DiskReader 

        self.reader = DiskReader(PXPaths.TXQ + self.sourlient.name, self.sourlient.batch,
                                 self.sourlient.validation, self.sourlient.diskReaderPatternMatching,
                                 self.sourlient.mtime, True, self.logger, eval(self.sourlient.sorter), self.sourlient)
        
        self.debug = True  # Debugging switch
        self.justConnect = False  # Boolean that indicates when a connexion just occur
        
        self.totBytes = 0

        #self.printInitInfos()
        self.makeConnection()
        #self.run()

    def setIgniter(self, igniter):
        self.igniter = igniter

    def printInitInfos(self):
        print("********************* Init. Infos ****************************")
        print("Remote Host: %s" % self.host)
        print("Port R: %s" % self.portR)
        print("Port S: %s" % self.portS)
        print("Remote Address: %s" % self.remoteAddress)
        print("Timeout: %4.1f" % self.timeout)
        print("Write Path: %s" % self.writePath)
        print("Subscriber: %s" % self.subscriber)
        print("**************************************************************")

    def reconnect(self):
        try:
            #poller.unregister(self.socket.fileno())
            self.socket.close()
        except:
            (type, value, tb) = sys.exc_info()
            self.logger.error("Unable to close the socket! Type: %s, Value: %s" % (type, value))

        # FIXME: Possibly some variable resetting should occur here?
        self.logger.info("Sleeping %d seconds (just before makeConnection())" % (self.sleepBetweenConnect))
        time.sleep(self.sleepBetweenConnect)
        self.makeConnection()

    def makeConnection(self):
        if self.subscriber:
            # The Subscriber first listens for a connection from Provider(MHS)
            self.socket = self._listen(self.portR, self.logger)
            if self.socket:
                self.logger.info("Subscriber has been connected by Provider")
                #self.run()
            else:
                # The Subscriber try to connect to the Provider(MHS)
                self.remoteAddress = (self.host, self.portS)
                self.logger.info("The subscriber will try to connect to MHS(%s)" % str(self.remoteAddress))
                self.socket = self._connect(self.remoteAddress, self.logger)
                #self.run()

        else: # Provider(MHS) case
            # The Provider first try to connect to the Subscriber
            self.remoteAddress = (self.host, self.portS)
            self.socket = self._connect(self.remoteAddress, self.logger)
            if self.socket:
                self.logger.info("Provider has completed the connection")
                #self.run()
            else:
                # The Provider(MHS) listens for a connection from Subscriber
                self.socket = self._listen(self.portR, self.logger)
                if self.socket:
                    self.logger.info("Provider has been connected by the subscriber")
                    #self.run()
                else:
                    self.logger.error("No socket (NONE)")
        self.justConnect = True
        

    def _connect(self, remoteAddress, logger):
        trials = 0
        if self.subscriber:
            maxTrials = 1000
        else:
            maxTrials = 3 

        while trials < maxTrials:
            if trials == 12:
                self.sleepBetweenConnect = 60
            socketSender = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            socketSender.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
            socketSender.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            socketSender.settimeout(self.timeout)
            #print socketSender.getsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF)
            #socketSender.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF,4096)
            #print socketSender.getsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF)
            #socketSender.setblocking(True)
            trials += 1
            try:
                socketSender.connect(remoteAddress)
                logger.info("Sender is now (after %d trial(s)) connected to: %s" % (trials, str(remoteAddress)))
                break
            except socket.gaierror, e:
                logger.error("Address related error connecting to receiver: %s" % e)
                sys.exit(1)
            except socket.error, e:
                (type, value, tb) = sys.exc_info()
                logger.error("Type: %s, Value: %s, Sleeping %d seconds ..." % (type, value, self.sleepBetweenConnect))
                socketSender.close()
                socketSender = None
                time.sleep(self.sleepBetweenConnect)