#!/usr/bin/env python ############################################################################# # Copyright (C) DSTC Pty Ltd (ACN 052 372 577) 1997, 1998, 1999, 2000 # All Rights Reserved. # # The software contained on this media is the property of the DSTC Pty # Ltd. Use of this software is strictly in accordance with the # license agreement in the accompanying LICENSE.HTML file. If your # distribution of this software does not contain a LICENSE.HTML file # then you have no rights to use this software in any manner and # should contact DSTC at the address below to determine an appropriate # licensing arrangement. # # DSTC Pty Ltd # Level 7, GP South # Staff House Road # University of Queensland # St Lucia, 4072 # Australia # Tel: +61 7 3365 4310 # Fax: +61 7 3365 4311 # Email: enquiries@dstc.edu.au # # This software is being provided "AS IS" without warranty of any # kind. In no event shall DSTC Pty Ltd be liable for damage of any # kind arising out of or in connection with the use or performance of # this software. # # Project: Fnorb # File: $Source: /cvsroot/fnorb/fnorb/orb/IIOPAcceptor.py,v $ # Version: @(#)$RCSfile: IIOPAcceptor.py,v $ $Revision: 1.12 $ # ############################################################################# """ IIOPAcceptor (part of the 'Reactor' pattern). """ # Standard/built-in modules. import socket # Fnorb modules. import Acceptor, CORBA, GIOP, GIOPServer, EventHandler, Reactor # IIOP protocol modules. import IIOPConnection class IIOPAcceptor(Acceptor.Acceptor, EventHandler.EventHandler): """ Acceptor (part of the 'Reactor' pattern). """ def __init__(self, address=None): """ Constructor. 'address' is the address to use when creating my endpoint. """ # Unpack the address. # # fixme: address abstraction! if address is None: address = ('', 0) try: # Create a socket on which to listen for connection requests. self.__socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.__socket.bind(address) self.__socket.listen(5) # Get the host name, the IP address and the port number of the # socket. # Get the fully qualified host name hostname, aliaslist, iplst = socket.gethostbyaddr(socket.gethostname()) aliaslist = [hostname] + aliaslist tmphost = "" for currHost in aliaslist: for char in list(currHost): if char == ".": tmphost = currHost break # If none have a period then use the original hostname self.__host = tmphost or hostname or host (self.__ip_address, self.__port) = self.__socket.getsockname() except socket.error: raise CORBA.COMM_FAILURE() # System exception. # Get a reference to the active reactor. self.__reactor = Reactor.Reactor_init() # Register our interest in read events (ie. connection requests) with # the Reactor. self.__reactor.register_handler(self, Reactor.READ) self.__giop_version = GIOP.Version(1, 2) return ######################################################################### # Acceptor interface. ######################################################################### def address(self): """ Return the address of the acceptor's endpoint. """ # fixme: Address abstraction! return (self.__host, self.__port) ######################################################################### # EventHandler interface. ######################################################################### def handle_event(self, mask): """ Callback method to handle all events except close events. """ # Read event. if mask & Reactor.READ: self.__read_event() # Exception event. elif mask & Reactor.EXCEPTION: self.__exception_event() return def handle_close(self): """ Callback method to handle close events. """ # Withdraw my Reactor registration. self.__reactor.unregister_handler(self, Reactor.READ) # Clean up my socket. try: self.__socket.close() except socket.error: pass del self.__socket return def handle(self): """ Return my underlying I/O handle. In this case, my I/O handle is the file descriptor of my socket. """ return self.__socket.fileno() ######################################################################### # Private interface. ######################################################################### def __read_event(self): """ Handle a read event. """ try: # 'Accept' the connection (in TCP/IP there is, in fact, no way to # reject it!). (client_socket, address) = self.__socket.accept() # Create a 'Connection' instance to look after the socket. connection = IIOPConnection.IIOPConnection(client_socket) # Create a server to handle client operation requests. GIOPServer.GIOPServer(self.__giop_version, connection) except socket.error: self.__exception_event() return def __exception_event(self): """ Handle an exception event. """ # Clean up. self.handle_close() return #############################################################################