Socket auslesen und Datenverarbeitung – SELFHTML-Forum Forum als Ergänzung zum SELFHTML-Wiki und zur Dokumentation SELFHTML https://forum.selfhtml.org/self Socket auslesen und Datenverarbeitung Wed, 28 Sep 05 19:49:48 Z https://forum.selfhtml.org/self/2005/sep/28/socket-auslesen-und-datenverarbeitung/879508#m879508 https://forum.selfhtml.org/self/2005/sep/28/socket-auslesen-und-datenverarbeitung/879508#m879508 <p>Hallo zusammen,</p> <p>mittels Perl und IO::Socket::INET stelle ich eine Client-Server<br> Verbindung her. Nun werden vom Server allerhand Informationen zum<br> Client gesendet, die ich in einer while-Schleife verarbeite.</p> <p>Nun weiß ich nicht so recht, an welcher Stelle ich die Daten in<br> meinem Skript verarbeiten soll... prüfen (bei bestimmten Daten<br> wird eine eMail generiert), filtern, die Daten aufteilen und<br> tabellenartig wegschreiben.</p> <p>Ich möchte die Verarbeitung gerne schon in der Schleife</p> <p>while ($socket) {<br>       # Verarbeitung<br>       # eMail falls notwendig<br>       # Wegschreiben<br>    }</p> <p>durchführen. Könnte was dagegen sprechen?</p> <p>Ich habe mal irgendwo gelesen, dass man die Daten zunächst aufnehmen<br> sollte und später verarbeiten, damit die Client-Server Verbindung<br> um so schneller geschlossen werden kann. Warum jedoch kann ich mir<br> nicht so recht vorstellen.</p> <p>Habt Ihr ein paar Tipps für mich?</p> <p>Greez,<br> opi</p> <div class="signature">-- <br> Selfcode: ie:( fl:( br:^ va:) ls:] fo:) rl:( n4:? ss:| de:] ch:? mo:|<br> </div> Socket auslesen und Datenverarbeitung Sat, 01 Oct 05 19:28:36 Z https://forum.selfhtml.org/self/2005/sep/28/socket-auslesen-und-datenverarbeitung/879509#m879509 https://forum.selfhtml.org/self/2005/sep/28/socket-auslesen-und-datenverarbeitung/879509#m879509 <p>Tag opi.</p> <blockquote> <p>mittels Perl und IO::Socket::INET stelle ich eine Client-Server<br> Verbindung her. Nun werden vom Server allerhand Informationen zum<br> Client gesendet, die ich in einer while-Schleife verarbeite.</p> </blockquote> <p>Jepp, das ist das normale Vorgehen.</p> <blockquote> <p>Ich habe mal irgendwo gelesen, dass man die Daten zunächst aufnehmen<br> sollte und später verarbeiten, damit die Client-Server Verbindung<br> um so schneller geschlossen werden kann. Warum jedoch kann ich mir<br> nicht so recht vorstellen.</p> </blockquote> <p>Ich vermute mal, dass du auf Folgendes hinauswillst:</p> <p>Wenn du mehrere eingehende Verbindungen nacheinander entgegennehmen willst, geschieht das ja für gewöhnlich so:</p> <pre><code class="block language-perl"><span class="token keyword">use</span> strict<span class="token punctuation">;</span> <span class="token keyword">use</span> IO<span class="token punctuation">:</span><span class="token punctuation">:</span>Sockets<span class="token punctuation">;</span> <span class="token keyword">my</span> <span class="token variable">$server</span> <span class="token operator">=</span> IO<span class="token punctuation">:</span><span class="token punctuation">:</span>Socket<span class="token punctuation">:</span><span class="token punctuation">:</span>INET<span class="token operator">-></span>new<span class="token punctuation">(</span><span class="token string">"www.example.org:80"</span><span class="token punctuation">)</span> <span class="token operator">or</span> <span class="token keyword">die</span> <span class="token string">"Error connecting to Server: $@\n"</span><span class="token punctuation">;</span> <span class="token keyword">my</span> <span class="token variable">$client</span><span class="token punctuation">;</span> <span class="token keyword">my</span> <span class="token variable">$answer</span><span class="token punctuation">;</span> <span class="token keyword">while</span><span class="token punctuation">(</span><span class="token variable">$client</span> <span class="token operator">=</span> <span class="token variable">$server</span><span class="token operator">-></span>accept<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$answer</span> <span class="token operator">=</span> <span class="token operator"><</span><span class="token variable">$client</span><span class="token operator">></span><span class="token punctuation">;</span> <span class="token comment"># tu was mit $answer </span> <span class="token punctuation">}</span> close<span class="token punctuation">(</span><span class="token variable">$server</span><span class="token punctuation">)</span><span class="token punctuation">;</span> </code></pre> <p>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 <a href="http://perldoc.perl.org/Fcntl.html" rel="nofollow noopener noreferrer">Fcntl</a>.</p> <p>Falls deine Serverantwort nicht einzeilig sein sollte, müsstest du natürlich entsprechend anders vorgehen:</p> <pre><code class="block language-perl"><span class="token keyword">while</span><span class="token punctuation">(</span><span class="token variable">$client</span> <span class="token operator">=</span> <span class="token variable">$server</span><span class="token operator">-></span>accept<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">while</span><span class="token punctuation">(</span><span class="token operator"><</span><span class="token variable">$client</span><span class="token operator">></span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># tu was mit der aktuellen Zeile </span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> </code></pre> <p>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:</p> <pre><code class="block language-perl"><span class="token keyword">while</span><span class="token punctuation">(</span><span class="token variable">$client</span> <span class="token operator">=</span> <span class="token variable">$server</span><span class="token operator">-></span>accept<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">@lines</span> <span class="token operator">=</span> <span class="token operator"><</span><span class="token variable">$client</span><span class="token operator">></span><span class="token punctuation">;</span> <span class="token keyword">foreach</span><span class="token punctuation">(</span><span class="token variable">@lines</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># tu was mit der aktuellen Zeile </span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> </code></pre> <p>Sehr ausführlich beschrieben ist es in <a href="http://www.foo.be/docs/tpj/issues/vol3_3/tpj0303-0002.html" rel="nofollow noopener noreferrer">http://www.foo.be/docs/tpj/issues/vol3_3/tpj0303-0002.html</a>.</p> <p>Siech*in der Hoffnung, nichts übersehen/vergessen zu haben*fred</p> <div class="signature">-- <br> <a href="http://sniplets.anaboe.net" rel="nofollow noopener noreferrer">Codeschnipsel gefällig?</a> || <a href="http://www.steuerwerkstatt.de/existenzgruendung.php" rel="nofollow noopener noreferrer">Wieder Online: Existenzgründer-FAQ</a> </div> Socket auslesen und Datenverarbeitung Sun, 02 Oct 05 11:37:17 Z https://forum.selfhtml.org/self/2005/sep/28/socket-auslesen-und-datenverarbeitung/879510#m879510 https://forum.selfhtml.org/self/2005/sep/28/socket-auslesen-und-datenverarbeitung/879510#m879510 <p>Hallo Siechfred,</p> <blockquote> <p>Ich vermute mal, dass du auf Folgendes hinauswillst:</p> <p>Wenn du mehrere eingehende Verbindungen nacheinander entgegennehmen willst, geschieht das ja für gewöhnlich so:</p> </blockquote> <p>nicht so ganz.</p> <p>Ich habe einen Agenten auf jedem Server laufen.</p> <p>while (my $client = $server->accept()) {<br>    my $q = <$client>;<br>    # Anfrage Verarbeiten<br>    print $client "meine Antwort";<br>    # ca. 600kb werden zurück gesendet<br> }</p> <p>Und hier schicke ich meine Anforderung an den Agenten:</p> <p>my $q = "anfrage an der Agenten";</p> <p>my $socket = IO::Socket::INET->new(<br>                 PeerAddr => $ip,<br>                 PeerPort => $service,<br>                 Proto    => "tcp",<br>                 Type     => SOCK_STREAM<br> )</p> <p>print $socket "$q\n";</p> <p>while (<$socket>) {<br>    # [1] Antwort bearbeiten<br> }</p> <p>close $socket;</p> <p>[1] genau diese Stelle meinte ich. Die Daten müssen verarbeitet und<br> in mehrere Dateien weggeschrieben werden.</p> <p>Wäre es also ratsamer, die Daten zunächst in ein Array oder einen<br> Hash zu packen oder kann ich sie auch sofort verarbeiten und<br> wegschreiben?</p> <p>while (<$socket>) {<br>    last if /^EOF/;<br>    # push @$arr, $_;<br>    # oder<br>    # Verarbeitung und Wegschreiben<br> }</p> <p>Greez,<br> opi</p> <div class="signature">-- <br> Selfcode: ie:( fl:( br:^ va:) ls:] fo:) rl:( n4:? ss:| de:] ch:? mo:|<br> </div> Socket auslesen und Datenverarbeitung Mon, 03 Oct 05 10:42:57 Z https://forum.selfhtml.org/self/2005/sep/28/socket-auslesen-und-datenverarbeitung/879513#m879513 https://forum.selfhtml.org/self/2005/sep/28/socket-auslesen-und-datenverarbeitung/879513#m879513 <p>Tag opi.</p> <blockquote> <p>while (<$socket>) {<br>    # [1] Antwort bearbeiten<br> }<br> Wäre es also ratsamer, die Daten zunächst in ein Array oder einen<br> Hash zu packen oder kann ich sie auch sofort verarbeiten und<br> wegschreiben?</p> </blockquote> <p>Das ist m.E. eine Frage der Geschwindigkeit und des verfügbaren Speichers. Natürlich könntest du dir eine Datenstruktur anlegen, die zunächst die erhaltenen Daten speichert, die Verbindung wieder beendet und dann die Verbindung zum nächsten Server aufbaut usw., nach Abrufen aller Verbindungen würdest du dann diese Datenstruktur im nächsten Schritt auswerten. Und diese Struktur kann halt einen ziemlich großen Umfang annehmen, was möglicherweise zu Lasten des Speichers geht. Du kannst natürlich auch gleich die Daten in einer while-Schleife verarbeiten. Letztendlich ist es eine Frage der Performance des Scripts, das müsstest du halt testen. Die Verbindungsdauer jedenfalls dürfte nur geringfügig variieren, egal, ob du die Daten zwischenspeicherst (was m.E. die schnellere Variante wäre) oder "on the fly" auswertest. Eventuell wäre ein Mittelweg in der Form gangbar, dass du in der while-Schleife die Daten auswertest und das *Ergebnis* in einer Datenstruktur ablegst, die dann später ausgewertet wird (E-Mails versenden u.ä.).</p> <p>Siechfred</p> <div class="signature">-- <br> <a href="http://sniplets.anaboe.net" rel="nofollow noopener noreferrer">Codeschnipsel gefällig?</a> || <a href="http://www.steuerwerkstatt.de/existenzgruendung.php" rel="nofollow noopener noreferrer">Wieder Online: Existenzgründer-FAQ</a> </div> Socket auslesen und Datenverarbeitung Mon, 03 Oct 05 11:42:33 Z https://forum.selfhtml.org/self/2005/sep/28/socket-auslesen-und-datenverarbeitung/879511#m879511 https://forum.selfhtml.org/self/2005/sep/28/socket-auslesen-und-datenverarbeitung/879511#m879511 <p>Hallo,</p> <p>dein skript stellt ja den client da. Du riskierst in dem Skript mit der direkten Verarbeitung incl wegschreiben und etc, dass, wenn das Wegschreiben nicht sofort klappt (gelockte Datei etc), einfach die Verbindung so lange offen bleibt, bis die Daten verarbeitet sind. Nun ist halt die Frage, ob es dir wichtiger ist, dass das Skript weniger Speicher verbraucht, oder die Verbindung schneller beendet wird.</p> <p>gruss</p> <div class="signature">-- <br> no strict;<br> no warnings;<br> 79.78 cups of Coffee (Brewed) + Me = Death<br> Reklame ist die Kunst, auf den Kopf zu zielen und die Brieftasche zu treffen. </div> Socket auslesen und Datenverarbeitung Mon, 03 Oct 05 13:34:10 Z https://forum.selfhtml.org/self/2005/sep/28/socket-auslesen-und-datenverarbeitung/879512#m879512 https://forum.selfhtml.org/self/2005/sep/28/socket-auslesen-und-datenverarbeitung/879512#m879512 <p>Hallo Eternius,</p> <blockquote> <p>Hallo,</p> <p>dein skript stellt ja den client da. Du riskierst in dem Skript mit der direkten Verarbeitung incl wegschreiben und etc, dass, wenn das Wegschreiben nicht sofort klappt (gelockte Datei etc), einfach die Verbindung so lange offen bleibt, bis die Daten verarbeitet sind.</p> </blockquote> <p>daran hatte ich noch garnicht gedacht! Allerdings habe ich den<br> Vorteil, dass der Server und der Client einzig und allein über diese<br> Verbindung unterhalten.</p> <blockquote> <p>Nun ist halt die Frage, ob es dir wichtiger ist, dass das Skript weniger Speicher verbraucht, oder die Verbindung schneller beendet wird.</p> </blockquote> <p>Ich werde mal Testen, auf wieviel Speicher der Prozess anwächst und<br> dann meine Schlüsse ziehen!</p> <p>Bis hierhin danke schonmal!</p> <p>Greez,<br> opi</p> <div class="signature">-- <br> Selfcode: ie:( fl:( br:^ va:) ls:] fo:) rl:( n4:? ss:| de:] ch:? mo:|<br> </div> Socket auslesen und Datenverarbeitung Mon, 03 Oct 05 13:52:56 Z https://forum.selfhtml.org/self/2005/sep/28/socket-auslesen-und-datenverarbeitung/879514#m879514 https://forum.selfhtml.org/self/2005/sep/28/socket-auslesen-und-datenverarbeitung/879514#m879514 <p>Hallo,</p> <blockquote> <p>Das ist m.E. eine Frage der Geschwindigkeit und des verfügbaren Speichers. Natürlich könntest du dir eine Datenstruktur anlegen, die zunächst die erhaltenen Daten speichert, die Verbindung wieder beendet und dann die Verbindung zum nächsten Server aufbaut usw.,</p> </blockquote> <p>Es ist nur so, dass die Datenstruktur ziemlich groß ist. Ich würde<br> die Daten in einen Hash packen, der dann allerdings sehr viele<br> Schlüssel haben wird. Da wäre dann auch schon gleich meine nächste<br> Frage...</p> <p>Ist es üblich, dass man die Schlüsselnamen für alles mögliche<br> missbraucht? Beispielsweise würde ich, um den Hash nach der<br> Verarbeitung besser auslesen zu können, den ersten Key als Datei-<br> namen nutzen und zu guter Letzt die Daten Zeilenweise als Array<br> dort ablegen. Beispiel:</p> <p>Beispiel-Hash:</p> <pre><code class="block language-perl"><span class="token keyword">use</span> Fcntl <span class="token string">qw(:DEFAULT :flock)</span><span class="token punctuation">;</span> <span class="token keyword">my</span> <span class="token variable">$hash</span> <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token variable">$hash</span><span class="token operator">-></span><span class="token punctuation">{</span>Datei_1<span class="token punctuation">}</span><span class="token operator">-></span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"1 2 3 4 5"</span><span class="token punctuation">;</span> <span class="token variable">$hash</span><span class="token operator">-></span><span class="token punctuation">{</span>Datei_1<span class="token punctuation">}</span><span class="token operator">-></span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"1 2 3 4 5"</span><span class="token punctuation">;</span> <span class="token variable">$hash</span><span class="token operator">-></span><span class="token punctuation">{</span>Datei_2<span class="token punctuation">}</span><span class="token operator">-></span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"1 2 3 4 5"</span><span class="token punctuation">;</span> <span class="token variable">$hash</span><span class="token operator">-></span><span class="token punctuation">{</span>Datei_2<span class="token punctuation">}</span><span class="token operator">-></span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"1 2 3 4 5"</span><span class="token punctuation">;</span> <span class="token variable">$hash</span><span class="token operator">-></span><span class="token punctuation">{</span>Datei_3<span class="token punctuation">}</span><span class="token operator">-></span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"1 2 3 4 5"</span><span class="token punctuation">;</span> <span class="token variable">$hash</span><span class="token operator">-></span><span class="token punctuation">{</span>Datei_3<span class="token punctuation">}</span><span class="token operator">-></span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"1 2 3 4 5"</span><span class="token punctuation">;</span> <span class="token variable">$hash</span><span class="token operator">-></span><span class="token punctuation">{</span>Datei_4<span class="token punctuation">}</span><span class="token operator">-></span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"1 2 3 4 5"</span><span class="token punctuation">;</span> <span class="token comment"># Daten wegschreiben </span> <span class="token keyword">foreach</span> <span class="token keyword">my</span> <span class="token variable">$file</span> <span class="token punctuation">(</span>keys <span class="token variable">%</span><span class="token punctuation">{</span><span class="token variable">$hash</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">die</span> <span class="token string">"datei $file kann nicht geöffnet werden\n"</span> <span class="token keyword">unless</span> sysopen FILE<span class="token punctuation">,</span><span class="token string">"./$file"</span><span class="token punctuation">,</span>O_WRONLY <span class="token operator">|</span> O_APPEND <span class="token operator">|</span> O_CREAT<span class="token punctuation">;</span> flock<span class="token punctuation">(</span>FILE<span class="token punctuation">,</span>LOCK_EX<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">foreach</span> <span class="token keyword">my</span> <span class="token variable">$line</span> <span class="token punctuation">(</span><span class="token variable">@</span><span class="token punctuation">{</span><span class="token variable">$hash</span><span class="token operator">-></span><span class="token punctuation">{</span><span class="token variable">$file</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">print</span> FILE <span class="token string">"$_\n"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> close FILE<span class="token punctuation">;</span> <span class="token punctuation">}</span> </code></pre> <p>Greez,<br> opi</p> <div class="signature">-- <br> Selfcode: ie:( fl:( br:^ va:) ls:] fo:) rl:( n4:? ss:| de:] ch:? mo:|<br> </div>