E.5.2 Klasse zur parallelen Verwaltung einer Socketmenge (c_multiconn)

# -------------------------------------------------------------
# Projekt : Digitale Bibliotheken Projekt
# Uni-Frankfurt/M, Professur Telematik und
# verteilte Systeme, Prof. O. Drobnik
# Diplomarbeit, Matzen,Hans, 1997
# Dateiname : c_multiconn.py
# Datum : 03.11.1997
# letzte Änderung :
# Autor : Hans Matzen, 1997, Frankfurt/M, Deutschland
# Sprache : Python v1.4
# Beschreibung : Klasse zur gleichzeitigen Verwaltung
# mehrerer TCP/IP Verbindungen
# Anmerkungen :
#
# -------------------------------------------------------------
 
# imports
import socket
import select
import ERRNO
import errno
 
 
class c_multiconn:
 
    #
    # Konstruktor
    #
    def __init__(self):
        # initialisiere Liste der Filedeskriptoren
        self.fdlist=[]
        # initialisiere Dictionary fuer Sockets
        self.sockdict={}
 
    #
    # Gibt alle vorgehaltenen Informationen ueber
    # die Sockets aus. (for debugging)
    #
    def print_lists(self):
        print "----------------------------------"
        print self.fdlist
        print self.sockdict
        print "----------------------------------"
 
 
    #
    # erzeugt einen neuen Socket mit der durch host, port
    # gegebene Adresse, werden host, port nicht uebergeben
    # wird eine freie Adresse benutzt
    #
    def open_sock(self,host="",port=0):
        conns=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        try:
            conns.bind(host,port)
            fd=conns.fileno()
            self.fdlist.append(fd)
            self.sockdict[fd]=conns
            return fd
        except:
            return -1
 
    #
    # schliesst den Socket mit Nummer socknr
    # und traegt ihn aus den Listen aus
    #
    def close_sock(self,socknr):
        sock=self.sockdict[socknr]
        try:
            sock.shutdown(1)
        except:
            sock.close()
 
        del sock
        self.fdlist.remove(socknr)
        del self.sockdict[socknr]
        return 1
     
    #
    # wartet auf allen Sockets auf Leseereignisse
    # und gibt eine Liste der aktiven Sockets zurueck
    #
    def wait_event(self,sec=0):
        active=([],[],[])
        if sec==0:
            try:
                active=select.select(self.fdlist,[],[])
            except select.error:
                pass
        else:
            active=select.select(self.fdlist,[],[],sec)
        return active[0]
 
    #
    # schreibt eine Nachricht auf den Socket mit Nummer socknr
    # und gibt die Anzahl der geschriebenen Bytes zurueck
    #
    def write_sock(self,socknr,sendstr):
        sock=self.sockdict[socknr]
        return sock.send(sendstr)
         
    #
    # liest eine Nachricht vom Socket mit Nummer socknr
    # und gibt sie zurueck
    #
    def read_sock(self,socknr):
        sock=self.sockdict[socknr]
        return sock.recv(64000)
 
 
    def poll_sock(self,socknr,secs):
        pass
 
    #
    # baut fuer Socket mit Nummer socknr eine Verbindung
    # mit der Adresse host, port auf
    #
    def connect(self,socknr,host,port):
        sock=self.sockdict[socknr]
        return sock.connect(host,port)
 
    def listen(self,socknr):
        sock=self.sockdict[socknr]
        return sock.listen(5)
 
    #
    # wartet an Socket mit Nummer socknr auf
    # ein connect und gibt das neue Socketobjet zurueck
    #
    def accept(self,socknr):
        sock=self.sockdict[socknr]
        conns, addr =sock.accept()
        fd=conns.fileno()
        self.fdlist.append(fd)
        self.sockdict[fd]=conns
        return fd
 
    #
    # Gibt die lokale Adresse des Sockets mit
    # der Nummer socknr zurueck
    #
    def get_localaddr(self,socknr):
        sock=self.sockdict[socknr]
        return sock.getsockname()
 
    #
    # Destruktor
    #
    def __del__(self):
        # schliesse alle offenen Sockets
        for i in self.fdlist:
            self.close_sock(i)