# -------------------------------------------------------------
# Projekt : Digitale Bibliotheken Projekt
# Uni-Frankfurt/M, Professur Telematik und
# verteilte Systeme, Prof. O. Drobnik
# Diplomarbeit, Matzen,Hans, 1997
#
# Dateiname : p_net.py
# Datum : 03.11.1997
# letzte Änderung :
# Autor : Hans Matzen, 1997, Frankfurt/M, Deutschland
# Sprache : Python v1.4
# Beschreibung : Paket Netz, fasst alle Netzpaket-Klassen
# zusammen
#
# Anmerkungen :
#
# -------------------------------------------------------------
import c_tcp
import c_stopwait1
import c_send
import c_retrieve
Klasse c_tcp
# -------------------------------------------------------------
# Projekt : Digitale Bibliotheken Projekt
# Uni-Frankfurt/M, Professur Telematik und
# verteilte Systeme, Prof. O. Drobnik
# Diplomarbeit, Matzen,Hans, 1997
# Dateiname : c_tcp.py
# Datum : 03.11.1997
# letzte Änderung :
# Autor : Hans Matzen, 1997, Frankfurt/M, Deutschland
# Sprache : Python v1.4
# Beschreibung : Eine einfache TCP Connection Klasse
#
# Anmerkungen :
#
# -------------------------------------------------------------
# imports
import socket
import time
class c_tcpconn:
#
# Konstruktor, wird kein Port mit uebergeben
# dann wollen wir die Verbindung aufbauen(Client)
#
def __init__(self,host="",port=0):
self.sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
if port !=0:
try:
self.sock.bind(host,port)
self.typ="server"
except socket.error,msg:
print "---",msg,"---"
else:
self.typ="client"
#
# baut eine Verbindung mit host,port auf
#
def connect(self,host,port):
self.sock.connect(host,port)
#
# schreibt buff in den Socket
#
def send(self,buff):
if self.typ=="client":
self.sock.send(buff)
else:
self.peerconn.send(buff)
#
# wartet auf eine Nachricht die max. buffsize bytes lang ist
#
def recv(self,buffsize):
if self.typ=="client":
return self.sock.recv(buffsize)
else:
return self.peerconn.recv(buffsize)
#
# wie recv, wartet aber nur secs Sekunden
#
def poll(self,buffsize,secs=1):
polltime=secs
erg=""
if self.typ=="client":
self.sock.setblocking(0)
else:
self.peerconn.setblocking(0)
while erg=="" and polltime>0:
try:
if self.typ=="client":
erg=self.sock.recv(buffsize)
else:
erg=self.peerconn.recv(buffsize)
except socket.error:
erg=""
time.sleep(1)
polltime=polltime-1
if self.typ=="client":
self.sock.setblocking(1)
else:
self.peerconn.setblocking(1)
return erg
#
# baut eine evtl. bestehende Verbindung ab
# und schliesst die Sockets
#
def close(self):
if self.typ=="server":
self.sock.close()
self.peerconn.shutdown(1)
else:
self.sock.shutdown(1)
return
#
# liefert die lokale Adresse zurueck
#
def getaddr(self):
return [socket.gethostname(),self.sock.getsockname()]
#
#liefert die Remote-Adresse zurueck
#
def getpeeraddr(self):
if self.typ=="client":
return self.sock.getpeername()
else:
return self.peerconn.getpeername()
Klasse c_stopwait1
# -------------------------------------------------------------
# Projekt : Digitale Bibliotheken Projekt
# Uni-Frankfurt/M, Professur Telematik und
# verteilte Systeme, Prof. O. Drobnik
# Diplomarbeit, Matzen,Hans, 1998
# Dateiname : c_stopwait1.py
# Datum : 09.12.1997
# letzte Änderung :
# Autor : Hans Matzen, 1997, Frankfurt/M, Deutschland
# Sprache : Python v1.4
# Beschreibung : Hier ist eine einfache Stop-Wait Protokoll
# Maschine als Klasse implementiert.
# Anmerkungen : Diese Klasse kann verwendet werden, um
# aus Dokumentemethoden separate Netzverbindung
# zur Datenuebermittlung aufzubauen. Sie ist
# von der Klasse c_tcpconn abgeleitet.
# -------------------------------------------------------------
#
# import
from c_tcp import c_tcpconn
import c_bsio
import select
class c_stopwait1(c_tcpconn):
#
# Konstruktor, initialsiert Variable
# host,port gibt die Adresse des lokalen sockets an
# buffsize die Paketgroesse bei der Uebertragung
# timeout die Zeit (in Sekunden) die auf eine Bestaetigung
# gewartet wird, mittels debug=1 werden zusaetzliche
# Nachrichten ueber den Verlauf der uebertragung ausgegeben
#
def __init__(self,host="localhost",port=0,buffsize=512,timeout=5,debug=0):
# Konstruktor der Basisklasse aufrufen
c_tcpconn.__init__(self,host,port)
self.blocksize=buffsize
self.timeout=timeout
self.debug=debug
#
# Destruktor, trennt die Verbidung falls sie aufgebaut ist
#
def __del__(self):
try:
c_tcpconn.sock.close()
c_tcpconn.peerconn.close()
except:
pass
#
# fuehrt einen TCP connect an die durch
# host,port gegebene Adresse aus
#
def connect(self,host,port):
c_tcpconn.connect(self,host,port)
#
# wartet auf Verbidungsaufnahme durch eine Gegenstelle
#
def accept(self):
c_tcpconn.accept(self)
#
# sendet sendstr mittels des Stop-Wait Protokolls
# dabei wird die Nachricht segmentiert (blocksize)
# und die Uebertragung eines Pakets bei Uebertragunsfehlern
# bis zu 10 mal wiederholt
#
def send_str(self,sendstr):
hilf=sendstr
errcount=0
muell=self.poll(self.blocksize+1,1)
while len(hilf)>0 and errcount < 10:
self.send(hilf[:self.blocksize])
if self.debug:
print "send:",hilf[:self.blocksize],len(hilf[:self.blocksize])
ack=self.poll(8,self.timeout)
if self.debug:
print "recv:",ack
if ack=="ACK"+str(len(hilf[:self.blocksize])):
hilf=hilf[self.blocksize:]
else:
errcount=errcount+1
# Konnten wir alles uebertragen
if errcount<10:
ackend=0
while ackend==0 and errcount <10:
self.send("END")
ack=self.poll(8,self.timeout)
if self.debug:
print "recv:",ack
if ack=="ACK3":
ackend=1
else:
errcount=errcount+1
# Rueckgabewert ermitteln
if errcount < 10:
return 0
else:
return -1
#
# wie send_str, nur wird die Datei fname gesendet
#
def send_file(self,fname):
fd=c_bsio.c_bsio(fname,"r")
errcount=0
buff=" "
fd.open()
while buff!="" and errcount < 10:
buff=fd.read(self.blocksize)
self.send(self,buff)
ack=self.poll(8,self.timeout)
if self.debug:
print "recv:",ack
if ack!="ACK"+str(len(buff)):
fd.seek(-len(buff),0)
errcount=errcount+1
# Konnten wir alles uebertragen
if errcount<10:
ackend=0
while ackend==0 and errcount <10:
self.send(self,"END")
ack=self.poll(8,self.timeout)
if self.debug:
print "recv:",ack
if ack=="ACK3":
ackend=1
else:
errcount=errcount+1
fd.close()
# Rueckgabewert ermitteln
if errcount < 10:
return 0
else:
return -1
#
# empfaengt eine Zeichenkette von der Gegenstelle
#
def recv_str(self):
erg=""
buff=""
if self.typ=="server":
select.select([self.peerconn.fileno()],[],[])
else:
select.select([self.sock.fileno()],[],[])
while buff !="END":
buff=self.poll(self.blocksize,self.timeout)
if self.debug:
print "recv:",buff
if buff !="":
if buff !="END":
erg=erg+buff
self.send("ACK"+str(len(buff)))
if self.debug:
print "send:ACK"+str(len(buff))
else:
self.send("ERR")
if self.debug:
print "send:ERR"
return erg
#
# schreibt alle empfangenen Daten in die Datei mit
# dem Namen fname
#
def recv_file(self,fname):
fd=c_bsio.c_bsio(fname,"a+")
fd.open()
buff=""
while buff !="END":
buff=self.poll(self.blocksize,self.timeout)
if self.debug:
print "recv:",buff
if buff !="":
if buff !="END":
fd.write(buff)
self.send("ACK"+str(len(buff)))
if self.debug:
print "send:ACK",str(len(buff))
else:
self.send("ERR")
if self.debug:
print "send:ERR"
fd.close()
return 0
Klasse c_send
# -------------------------------------------------------------
# Projekt : Digitale Bibliotheken Projekt
# Uni-Frankfurt/M, Professur Telematik und
# verteilte Systeme, Prof. O. Drobnik
# Diplomarbeit, Matzen,Hans, 1998
# Dateiname : c_send.py
# Datum : 09.12.1997
# letzte Änderung :
# Autor : Hans Matzen, 1997, Frankfurt/M, Deutschland
# Sprache : Python v1.4
# Beschreibung : Diese Klasse versendet Teile eines bestimmten
# Dokuments ueber ein separate Netzverbindung
# Anmerkungen : Diese Klasse wird von den Klassen c_sgmlquery
# und c_stopwait1 abgeleitet.
#
# -------------------------------------------------------------
#
class c_send(c_sgmlquery,c_stopwait1):
#
# Konstruktor
# ident gibt die Dokument-ID an
# peerhost, peeport geben die Netzadresse des Peers an
# an diese Adresse werden alle Daten gesendet
# blocksize gibt die Paketgroese an (s. c_stopwait1)
# timeout gibt den timeout fuer das Warten auf Paket-
# bestaetigungen an.
#
def __init__(self,ident,peerhost,peerport,blocksize,timeout):
# Konstruktoren der Basisklassen aufrufen
c_sgmlquery.__init__(self,ident)
c_stopwait1.__init__("",0,blocksize,timeout)
self.peerport=peerport
self.peerhost=peerhost
self.connect(self.peerhost,self.peerport)
self.ident=ident
#
# Destruktor
#
def __del__(self):
# Destruktor der stopwait Klasse aufrufen
c_stopwait1.__del__()
#
# sendet als Bitstrom gespeicherte Daten
# und zwar von der Position start bis Position end
# wobei start und end absolute Positionen innerhalb
# des Bitstroms bezeichnen
#
def send_bs(self,start,end):
import c_bsio
from sc_globals import *
fname=DL_BSOUTPATH+str(ident)+'.bs'
fd=c_bsio.c_bsio(fname,'r')
fd.seek(start)
while fd.tell()<=end:
buff=fd.readline()
self.send_str(buff)
fd.close()
del fd
#
# sendet den Inhalt des tagcounten Tags mit Namen
# tagname an den Peer
#
def send_tagcontents(self,tagname,tagcount):
self.send_str(self.sgmlquery_tagcontens(tagname,tagcount))
return 0
#
# sendet den das tagcounte Tag mit Namen
# tagname an den Peer
#
def send_tag(self,tagname,tagcount):
self.send_str(self.sgmlquery_tag(tagname,tagcount))
return 0
#
# sendet die Tag-Struktur (Strukturbaum) des Dokuments
# an den Peer
#
def send_structure(self):
self.send_str( self.sgmlquery_structure())
return 0
#
# sendet das gesamte Dokument an den Peer
#
def send_doc(self):
self.send_str(self.sgmlquery_doc())
return 0