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)