Center for Biotechnology Bielefeld Bioinformatics Service Netzwerk - Programmierung Programmieren mit sockets Alexander Sczyrba Jan Krüger
Center for Biotechnology Bielefeld Bioinformatics Service Übersicht ● Datentypen und Konversionsfunktionen ● minimaler Client ● minimaler Server
Center for Biotechnology Bielefeld Bioinformatics Service Berkeley sockets ● sockets API, erstmals in 4.2BSD (1983) ● sehr genereller Aufbau: ● TCP/IP ● named pipes ● OSI-Protokolle ●... ● C-Funktionen ● Adress- und Portinformationen in structs ● spezielle Perl-Funktionen zur „Typkonversion“
Center for Biotechnology Bielefeld Bioinformatics Service Namen und Adressen ● Netzwerk-Interface durch IP-Adresse identifiziert ● dotted quad-Notation: ● „lesbare“ Namen durch Domain Name System (DNS) → ● keine Bijektion ● → bk-in-f147.1e100.net ● keine mathematische Funktion ● → ( , )
Center for Biotechnology Bielefeld Bioinformatics Service Adress-Konversion ● use Socket; ● Binärdarstellung für socket-Funktionen $iaddr = inet_aton(’ ’); $iaddr = inet_aton(’ ● alternativ $iaddr = gethostbyname(’ ● andere Richtung: $dotquad = inet_ntoa($iaddr); ● Namen ermitteln $name = gethostbyaddr($iaddr, AF_INET);
Center for Biotechnology Bielefeld Bioinformatics Service Aufgaben ● Wandle die folgenden Namen in Binärdarstellung um. Übersetze diese anschließend in dotted quad-Notation zurück, bzw. löse sie mit Hilfe des DNS wieder zu Namen auf. Führe das Skript mehrfach aus. Was ist zu beobachten? = qw(goldfinger goldfinger.TechFak.Uni-Bielefeld.DE ); ● Überprüfe die Ergebnisse mit dem Programm dig: $ dig
Center for Biotechnology Bielefeld Bioinformatics Service Weitere Funktionen ● Protokolle (vgl. /etc/protocols) $proto = getprotobyname(’tcp’); $tcp = getprotobynumber(6); ● Services (vgl. /etc/services) $service = getservbyname(’daytime’, ’tcp’); $daytime = getservbyport(13, ’tcp’);
Center for Biotechnology Bielefeld Bioinformatics Service Socket Adressen ● socket: Kombination aus Adresse und Port ● $sockaddr = sockaddr_in($port, $iaddr); ● andere Richtung ● ($port, $iaddr) = sockaddr_in($sockaddr); ● andere Adressfamilien ● $fifo = sockaddr_un(’/tmp/socket’);
Center for Biotechnology Bielefeld Bioinformatics Service Arbeitsweise Client socket()connect()I/Oclose() Server
Center for Biotechnology Bielefeld Bioinformatics Service Client-Code ● erzeugen eines sockets: ● socket(SOCKET, PF_INET, SOCK_STREAM, getprotobyname(’tcp’)) || die "can’t open socket: $!"; ● Verbindung herstellen: ● $sockaddr = sockaddr_in($peer_port, $peer_iaddr)); connect(SOCKET, $sockaddr) || die "can’t connect: $!"; ● SOCKET zum lesen/schreiben verwenden ● socket schließen: ● close(SOCKET);
Center for Biotechnology Bielefeld Bioinformatics Service Aufgaben ● Mach Dich mit dem ServiceServer (Material zu dieser Übung) vertraut und teste beide Services mit telnet ● Welche Services bietet der Server ? ● Schreibe ein Client-Programm, das eine Verbindung aufbaut, ein Commando absetzt (optional), alle Daten liest und die Verbindung wieder beendet. Der Zielrechner, der Zielport und das abzusetzende Kommando sollen als Argumente übergeben werden können. ● Probiere den Client mit dem ServiceServer aus ! ● Teste den Client auch mit dem WebServer der Technischen Fakultät ! Welcher Port, welches Protokoll und was für ein Kommando muss man benutzen um sich Einstiegsseite anzeigen zu lassen?
Center for Biotechnology Bielefeld Bioinformatics Service Socket- Informationen ● Port wird dynamisch zugewiesen (ephemeral port) ● beliebiges Interface bei multihomed host ● Informationen über sockets ermitteln: $mysockaddr = getsockname(SOCKET); $hissockaddr = getpeername(SOCKET); ● Weiterverarbeitung mit sockaddr_in()
Center for Biotechnology Bielefeld Bioinformatics Service Aufgaben ● Erweitere das Programm aus der letzten Aufgabe so, daß alle Daten zur Verbindung angezeigt werden. Zur Erinnerung: ● socket pair: (IP-AdresseL, PortL, IP-AdresseR, PortR) ● Rufe das Programm mehrfach auf. Was ist zu beobachten?
Center for Biotechnology Bielefeld Bioinformatics Service Arbeitsweise Server socket()bind()listen()accept()close() socket()conect()close() IOIO IOIO
Center for Biotechnology Bielefeld Bioinformatics Service Server-Code, Teil 1 ● socket(...) wie im Client ● socket an Port/Adresse binden: ● $sockaddr = sockaddr_in($local_port, INADDR_ANY); bind(SOCKET, $sockaddr) || die "can’t bind socket: $!"; ● passive open und backlog: ● listen(SOCKET, SOMAXCONN) || die "can’t listen: $!"; ● tatsächliche Größe des backlog abhängig vom Betriebssystem
Center for Biotechnology Bielefeld Bioinformatics Service Server-Code, Teil 2 ● Verbindungen entgegennehmen: ● $client_sockaddr = accept(CONNECT, SOCKET) ● accept() blockiert, bis Verbindung hergestellt ● $client_sockaddr enthält Informationen über peer ● typischerweise in Schleife: ● while ($client_sockaddr = accept(... )) {... } ● CONNECT zum lesen/schreiben verwenden ● am Ende Verbindungs-socket schließen: ● close(CONNECT);
Center for Biotechnology Bielefeld Bioinformatics Service Server-Code, cont. ● typischer Server-Code: ● socket(SOCKET, …) bind(SOCKET, …) listen(SOCKET, … ) ● while ( $sockaddr = accept(CONNECT, SOCKET)) { print CONNECT … oder line = close(CONNECT) ● } ● close(SOCKET) # optional
Center for Biotechnology Bielefeld Bioinformatics Service Aufgaben ● Schreibe einen Server, der auf Verbindungen wartet, zwei Zeilen Text sendet und dann die Verbindung schließt. Die erste Zeile soll den Client begrüßen, die zweite soll die aktuelle Uhrzeit ausgeben: ● hello goldfinger.TechFak.Uni-Bielefeld.DE, nice to meet you it’s Mon Jun 2 15:14: ● Du kannst den Server entweder mit dem Client aus der letzten Aufgabe oder mit dem Programm telnet testen.
Center for Biotechnology Bielefeld Bioinformatics Service Aufgaben ● Starte mehrere Clients gleichzeitig: ● client.pl & [enter] client.pl & [enter] client.pl & [enter] ● Was ist zu beobachten? ● Starte zwei Clients mit der gleichen Portnummer gleichzeitig: ● client.pl & [enter] client.pl & [enter] ● Was passiert? ● Beende den Server und versuche ihn sofort mit der gleichen Portnummer neu zu starten. Was passiert? ● Was passiert, wenn Du den Client mit CTRL-C abbrichst, während er Daten vom Server liest?