Siechfred: Socket auslesen und Datenverarbeitung

Beitrag lesen

Tag opi.

mittels Perl und IO::Socket::INET stelle ich eine Client-Server
Verbindung her. Nun werden vom Server allerhand Informationen zum
Client gesendet, die ich in einer while-Schleife verarbeite.

Jepp, das ist das normale Vorgehen.

Ich habe mal irgendwo gelesen, dass man die Daten zunächst aufnehmen
sollte und später verarbeiten, damit die Client-Server Verbindung
um so schneller geschlossen werden kann. Warum jedoch kann ich mir
nicht so recht vorstellen.

Ich vermute mal, dass du auf Folgendes hinauswillst:

Wenn du mehrere eingehende Verbindungen nacheinander entgegennehmen willst, geschieht das ja für gewöhnlich so:

use strict;  
use IO::Sockets;  
  
my $server = IO::Socket::INET->new("www.example.org:80")  
   or die "Error connecting to Server: $@\n";  
my $client;  
my $answer;  
while($client = $server->accept()) {  
  $answer = <$client>;  
  # tu was mit $answer  
}  
close($server);

Der Aufruf von accept() bewirkt, dass - falls sich keine Verbindung in der Warteschlange befindet - das Script solange stehen bleibt, bis eine Verbindung hereinkommt. Abhilfe schafft hier, non-blocking Sockets zu verwenden, Hilfe hierbei liefert das Modul Fcntl.

Falls deine Serverantwort nicht einzeilig sein sollte, müsstest du natürlich entsprechend anders vorgehen:

while($client = $server->accept()) {  
  while(<$client>) {  
    # tu was mit der aktuellen Zeile  
  }  
}

Normalerweise funktioniert der Zugriff über eine while-Schleife ein bisschen anders, denn Perl ist ja nicht blöd :-) Statt Zeile für Zeile in Echtzeit abzurufen, puffert Perl in weiser Voraussicht einen wesentlich größeren Inhalt der Antwort, um teure Systemaufrufe und damit Zeit zu sparen. Das kann man umgehen, indem man den Handle durch setzen von $| auf einen wahren Wert "hot" macht, und genau dies geschieht bei IO::Socket automatisch. Dann wird aber das Puffern unterbunden, somit sind mehr Systemaufrufe nötig und das Script wird langsamer ("Suffering from buffering"). Bei ein paar Zeilen ist das m.E. unproblematisch, bei großen Datenmengen kann es aber deshalb von Vorteil sein, den gesamten Inhalt in ein Array zu schreiben, um schnelleren Zugriff auf die Daten zu bekommen:

while($client = $server->accept()) {  
  @lines = <$client>;  
  foreach(@lines) {  
    # tu was mit der aktuellen Zeile  
  }  
}

Sehr ausführlich beschrieben ist es in http://www.foo.be/docs/tpj/issues/vol3_3/tpj0303-0002.html.

Siech*in der Hoffnung, nichts übersehen/vergessen zu haben*fred