Wie erstelle ich eine einfache nicht-blockende Server-Anwendung?
Inhalt:
Beispiel demonstriert die Verwendung von (Listen-)Sockets unter Perl.
Die Anwendung
use strict;
use warnings;
use IO::Socket::INET;
use IO::Select;
# Listensocket erstellen
my $server = IO::Socket::INET->new(
LocalPort => 2005,
type => SOCK_STREAM,
Reuse => 1,
Listen => 10
) or die "Server läuft nicht: $@\n";
my $select = IO::Select->new($server);
# warten, bis ein Client sich anmeldet, oder
# man von bereits angemeldeten Clients lesen kann
my $answer = 0;
while (my @readable = $select->can_read) {
for my $socket (@readable) {
if ($socket == $server) { # wenn der Socket gleich dem Listensocket ist
# Create a new socket
print "New client connects\n";
my $client = $socket->accept; # kehrt direkt zurück
$select->add($client); # in Select-Objekt aufnehmen
}
else { # sonst
my $line = $socket->getline; # von Socket lesen
if (defined $line) { # kein Fehler?
$line =~ s!\r?\n$!!g; # Zeilenumbruch entfernen
if (lc($line) eq 'quit') { # falls der Client beenden will
print "Client quits\n";
delete_socket($select, $socket);
}
else { # ansonsten, Message ausgeben
print "Client says: [$line]\n";
$socket->print("#".$answer++."\n");
}
}
else {
print "Connection closed by client\n";
delete_socket($select, $socket);
}
}
}
}
# kleine Routine, zum Zerstören des Sockets
sub delete_socket {
my ($sel, $sock) = @_;
$sel->remove($sock); # Socket aus Select-Objekt entfernen
$sock->close(); # Socket schliessen
}
Ergänzungen, Kommentare
Um zu sehen, dass der Server nun auch tut, was man will kann man sich nun einfach mit
telnet 127.0.0.1 2005 an ihn verbinden. Dann einfach eine Nachricht in das Telnet-Fenster eintippen, mit
abschicken und das Resultat im Server-Fenster beobachten. Die Eingabe des Wortes quit im Telnet-Fenster beendet die Verbindung zum Server.