Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

Netzwerk - Programmierung

Ähnliche Präsentationen


Präsentation zum Thema: "Netzwerk - Programmierung"—  Präsentation transkript:

1 Netzwerk - Programmierung
Nonblocking I/O Alexander Sczyrba Jan Krüger

2 Übersicht Grenzen von select Nonblocking I/O

3 Multiplexing per select: Wer schreibt?
Lesen oder Schreiben ? Multiplexing per select: Wer schreibt? aber: sysread/syswrite können blockieren deadlocks weiterhin möglich echoclient.pl: #!/usr/bin/env perl use IO::Socket; my $host = shift || ’localhost’; my $port = shift || ’echo’; my $socket = IO::Socket::INET->new("$host:$port") or die "Can’t connect to port $port at $host: $!\n"; while (defined(my $msg_out = <STDIN>)) { print $socket $msg_out; my $msg_in = <$socket>; print $msg_in; } $socket->close;

4 Lad Dir das Material zu dieser Übung herunter.
Aufgaben Lad Dir das Material zu dieser Übung herunter. Starte den ServiceServer (Material Übung Programmieren mit Sockets). Sieh Dir das Programm selectecho1.pl an. Verbinde es mit dem echo-Server. Was passiert, wenn Du das Programm mit dem slow-echo-Server reden läßt? Der slow-echo-Server arbeitet wie der echo-Server, gibt die gelesenen Daten aber mit vier Sekunden Verzögerung und in Blöcken von 30 Bytes zurück. selectecho1.pl: # create Select object, listen to socket my $select = IO::Select->new() || die "can’t create Select object: $!\n"; $select->add($socket); my $buffer; $| = 1; while (1) { # try to write = $select->can_write(); if { my $buffer = scalar(localtime()); my $len = syswrite($socket, $buffer); print "wrote ",substr($buffer, 0, $len),"\n"; } # try to read = $select->can_read(); if { my $len = sysread($socket, $buffer, 80); print "read ",$buffer,"\n"; # to something else print "do something else\n";

5 Aufgaben Das Programm selectecho2.pl verwendet eine Variante der select- Methode: my ($readers, $writers, undef) = IO::Select->select($select, $select, undef); Wie verhält sich das Programm im Zusammenspiel mit dem slow-echo-Server? Die Methoden can_read, can_write und select akzeptieren als weiteren Parameter einen timeout. Probiere in selectecho2.pl timeouts von 1 und 0 Sekunden aus. Was passiert? selectecho2.pl: while (1) { # look who’s ready to read or write my ($readers, $writers, undef) = IO::Select->select($select, $select, undef); # write, if the socket is writeable foreach { my $buffer = scalar(localtime()); my $len = syswrite($socket, $buffer); print "wrote ",substr($buffer, 0, $len),"\n"; } # read, if the socket is readable foreach { my $len = sysread($socket, $buffer, 80); print "read ",$buffer,"\n"; # do something else print "do something else\n";

6 Nonblocking I/O markiere handle/socket als nonblocking Schreib-/Lesezugriffe blockieren nicht entweder Daten oder Fehler falls Fehler: sysread/syswrite liefert undef $! wird auf EWOULDBLOCK gesetzt use Errno qw(:POSIX);

7 Nonblocking handles handle beim Öffnen als nonblocking markieren sysopen(FILE, $name, O_RDWR|O_NONBLOCK); nachträglich setzen: my $flags = fcntl(FILE, F_GETFL, 0); fcntl(FILE, F_SETFL, $flags | O_NONBLOCK); Makros in Modul Fcntl OO-Interface: $socket->blocking(0);

8 Beispiel use Errno qw(:POSIX); $socket->blocking(0);
while ($running) { my $len = sysread($socket, $buffer, $buflen); if (defined($len)) { if ($len) { print "read: $buffer\n"; } else { $running = 0; } } else { if ($! == EWOULDBLOCK) { print "BLOCK PREVENTED\n"; } else { die "unexpected error: $!\n"; } } }

9 Aufgabe Der Lotto-Server (teil des ServiceServer2) generiert im Abstand von| einer Sekunde jeweils eine Zufallszahl. Schreibe ein Programm, das solange von diesem Server liest, bis sechs verschiedene Zahlen gesammelt wurden. Verwende das Modul Rotor.pm, um anzuzeigen, daß Dein Programm auf die nächste Zufallszahl wartet. Sieh Dir das Programm rotor.pl zur Dokumentation an. lottoclient.pl: $socket->blocking(0); my %lotto = (); my $buffer; my $rotor = Rotor->new(); while (keys(%lotto) < 6) { # try to read number from socket my $len = sysread($socket, $buffer, 5); if (defined($len)) { if ($len == 0) { die "connection closed by peer\n"; } if (my ($num) = ($buffer =˜ /ˆ(\d+)$/)) { $lotto{$num} = 1; print "fetched $num\n"; } } else { if ($! == EWOULDBLOCK) { $rotor->print; }else { die "unexpected error: $!\n"; $socket->close(); print "your lucky numbers are ", join(’ ’, sort({$a<=>$b} keys(%lotto))),".\n";

10 Aufgabe Schreibe den echo-Client vom Anfang der Stunde mit Hilfe von nonblocking I/O so, um daß nicht mehr select verwendet wird. nonblockecho.pl: while (1) { # try to write my $buffer = scalar(localtime()); my $len = syswrite($socket, $buffer); if (defined($len)) { print "wrote ",substr($buffer, 0, $len),"\n"; } # try to read my $len = sysread($socket, $buffer, 80); print "read ",$buffer,"\n"; # do something else $rotor->print(); Eigentlich müßte noch der Fall behandelt werden, daß beim syswrite nur ein Teil des buffers geschrieben wird. Der Rest des zu sendenden Textes müßte dann in weiteren Versuchen geschrieben werden.


Herunterladen ppt "Netzwerk - Programmierung"

Ähnliche Präsentationen


Google-Anzeigen