php.de

Zurück   php.de > Webentwicklung > PHP-Fortgeschrittene

PHP-Fortgeschrittene Arbeiten mit PHP ohne Einschränkungen

Antwort
 
LinkBack Themen-Optionen
Alt 15.08.2010, 10:45  
Neuer Benutzer
 
Registriert seit: 28.08.2009
Beiträge: 15
PHP-Kenntnisse:
Fortgeschritten
dertechniker befindet sich auf einem aufstrebenden Ast
Standard socket_read laeuft in Endlosschleife

Hallo community,

ich hardere mittlerweile seit einigen Tagen mit einem Problem, das zwar durchaus in einigen Foren beschrieben, aber bisher nie mit einer funktionierenden Loesung beschrieben steht. Zudem sind die meisten Threads dazu alle einigen Jahre alt.

Konkret geht es um die Funktion socket_read. In einem Programm habe ich bisher immer eine ueberschaubare Anzahl an Bytes ausgetauscht, sodass das Einlesen von 1024 Bytes $buf = socket_read($socket, 1024, PHP_BINARY_READ) immer ausreichend war. Jetzt hat sich das Anforderungsprofil jedoch veraendert, sodass eine beliebige Anzahl an Bytes eingelesen werden muss. Die natuerliche Loesung ist, socket_read in einer Schleife solange aufzurufen, bis der Buffer leer ist; wobei dies auch bereits die kritische Stelle ist, da PHP genau dies nicht zu erkennen scheint. Dies laesst sich sehr schnell verdeutlichen, wenn man jeweils nur eine Laenge von 10 oder 20 Bytes einliest.

Hier sind die zwei exemplarischen Ansaetze, die ich im Netz zwar gefunden habe, aber die jedoch leider alle nicht funktionieren (aus Auskommentierte diente mir zu Debugzwecken):
PHP-Code:
    /*
            $reply = "";
            do {
                $recv = "";
                $recv = @ socket_read($socket, '20');
                if ($recv != "") {
                    $reply .= $recv;

                }
            } while ($recv != "");
    */ 
oder
PHP-Code:
    while(($out=@socket_read($socket10PHP_NORMAL_READ)) !== FALSE) {

        
// if ($out === FALSE) {
        //    continue;
        // }

        // $out = @socket_read($socket, 10);
        
$foo .= $out;

        
//if (empty($out)) {
        //    break;
        // }

        
if ($i == 80)
            die(
var_dump($foo2));

        
// if (strlen($out) < 10)
        //    break;

        
if (strlen($out) == 0) { break; }

        
$i++;
    } 
Das einzige, was das zweite Beispiel nicht in eine Endlosschleife verfallen laesst, ist, wenn ich pruefe, ob die Laenge des zuletzt eingelesenen Buffers kleiner als das Maximale (10 in diesem Fall) ist:
PHP-Code:
if (strlen($out) < 10)
  break; 
Das ganze halte ich jedoch fuer keine stabile Loesung, da ja zufaellig auch genau 10 Bytes uebertragen werden koennten. Dann wuerde das Script erneut socket_read aufrufen und wieder in die Endlosschleife wandern.

Die Hinweise hier PHP: socket_read - Manual haben leider auch nicht zielfuehrend weitergeholfen. Bei den obigen Scriptauszuegen wird die Endlosschleife immer erst dann unterbrochen, wenn der sendende Client beendet wird (CTRL+C).

Einige User haben irgendwann einfach fsockopen() verwendet, als sie offensichtlich nicht weitergekommen sind. Das ganze geht in meinem Fall leider nicht, da es sich hier um einen Socket Server handelt, der eine beliebige Menge an Daten einlesen koennen muss.

Ueber jegliche Ideen wuerde ich mich sehr freuen,
dertechniker
dertechniker ist offline   Mit Zitat antworten
Sponsor Mitteilung
PHP Code Flüsterer

Registriert seit: 21.08.2005
Beiträge: 4682
PHP-Kenntnisse:
Fortgeschritten

Alt 15.08.2010, 13:53  
Erfahrener Benutzer
 
Registriert seit: 17.07.2009
Beiträge: 262
PHP-Kenntnisse:
Fortgeschritten
Tiberius wird schon bald berühmt werden
Standard

soweit ich dich nun verstanden habe, würde ich sagen nimm socket_select. socket_select erkennt wenn Daten im socket zum lesen anliegen oder der socket zum schreiben bereit ist
Tiberius ist offline   Mit Zitat antworten
Alt 15.08.2010, 18:32  
Neuer Benutzer
 
Registriert seit: 28.08.2009
Beiträge: 15
PHP-Kenntnisse:
Fortgeschritten
dertechniker befindet sich auf einem aufstrebenden Ast
Standard

Hallo tiberius,

vielen Dank fuer das passende Stichwort - socket_select hat genau die gewuenschten Dienste erfuellt. Fuer alle, die noch auf das gleiche Problem stossen werden, hier die passenden Zeilen.

PHP-Code:
    $read = array($socket);
    
$write = array($socket);

    
$data '';
    while((
$buf=@socket_read($socket1024PHP_NORMAL_READ))) {

        
$data .= $buf;

        if (
$ret socket_select($read$write$except NULLNULL) < 2)
            break;

    } 
Noch als Anmerkung: $write durfte in meinem Fall nicht NULL sein, ansonsten lief es erneut in die Endlosschleife.

Vielen Dank noch mal,
dertechniker
dertechniker ist offline   Mit Zitat antworten
Alt 20.08.2010, 15:25  
Neuer Benutzer
 
Registriert seit: 28.08.2009
Beiträge: 15
PHP-Kenntnisse:
Fortgeschritten
dertechniker befindet sich auf einem aufstrebenden Ast
Standard

In den letzten Tagen ist mir noch ein weiteres - wenn auch seltsames - Phaenomen aufgefallen. Und zwar ist es bei mir vorgekommen, dass vom Server an einer Stelle via socket_write diverse Zeilen hintereinander geschickt werden, ohne dass dieser zwischendurch einliest (der Client schickt in dieser Zeit natuerlich auch nichts). Dabei habe ich beobachtet, dass der Server zwar alles richtig verschickt, aber beim Client immer wieder unterschiedliche Zeilen nicht ankommen, also als ob sie gar nicht versendet worden waeren.

Obiges nun schematisch dargestellt (S = Server, C = Client).

S -> Textzeile 1 -> C
S -> Textzeile ... -> C
S -> Textzeile n -> C

Erst als ich mein internes Protokoll so umgebaut hatte, dass jedes socket_write des Servers mit einer kurzen Empfangsbestaetigung beantwortet wurde (socket_write and socket_read jeweils im Wechsel), hat alles so geklappt wie es sollte. Schematisch:

S -> Textzeile 1 -> C
C -> Erhalten: Textzeile 1 -> S
S -> Textzeile ... -> C
C -> Erhalten: Textzeile ... -> S
S -> Textzeile n -> C
C -> Erhalten: Textzeile n -> S

Vielleicht ist das ja fuer andere spaeter noch hilfreich.

Gruesse,
dertechniker
dertechniker ist offline   Mit Zitat antworten
Alt 20.08.2010, 17:17  
Erfahrener Benutzer
 
Registriert seit: 17.07.2009
Beiträge: 262
PHP-Kenntnisse:
Fortgeschritten
Tiberius wird schon bald berühmt werden
Standard

würde sagen dass da bei dir was nicht richtig läuft, wie hast du socket read/write denn implementiert?
Tiberius ist offline   Mit Zitat antworten
Antwort


Themen-Optionen


Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
Events durch Endlosschleife RaRu PHP Tipps 2010 5 10.05.2010 12:12
Flash-Games-Portal soll performancelastige Endlosschleife haben Lesnivila PHP Tipps 2009 5 03.05.2010 17:03
Wie mit fsockopen endlosschleife? PHPFrisch PHP Tipps 2010 7 18.01.2010 10:31
[Erledigt] Endlosschleife warum? Thek PHP Tipps 2009 3 21.05.2009 22:59
HILFE! Meine Website laeuft unter Mac OS X / Safari nicht! SvenLittkowski HTML, Usability und Barrierefreiheit 14 19.03.2007 00:35
Endlosschleife ohne Script Adrenochrom PHP Tipps 2006 3 19.06.2006 06:37
Skript bleibt in Endlosschleife stecken PHP Tipps 2006 2 12.06.2006 16:44
Endlosschleife abbrechen - Geht das automatisch beim...... nicobischof PHP Tipps 2005-2 6 30.10.2005 15:41
warum endlosschleife? PHP Tipps 2005-2 6 31.08.2005 20:45
Autounterbrechung einer Endlosschleife seitens PHP PHP Tipps 2005-2 2 16.07.2005 15:09
Endlosschleife vom Apache aus verhindern Server, Hosting und Workstations 1 19.06.2005 17:49
Endlosschleife mit Array?! PHP Tipps 2004 8 05.11.2004 16:25
endlosschleife? konsti PHP-Fortgeschrittene 18 22.07.2004 09:46
Endlosschleife PHP Tipps 2004 2 03.06.2004 16:32

Besucher kamen über folgende Suchanfragen bei Google auf diese Seite
php socket_read, socket_read, socket_read php, php socket_read hangs, socket_read(, socket_read while, php socket read abbrechen, socked_read, socket_read php beispiel, $out = socket_read($socket,, socket_read php stuck, php socket_read array, php socket_read asynchron, php socket_rad, php socket_read break, socket_read socket server, php socket_read problem, php socket read, php socket_read endlos, $ret = socket_select

Alle Zeitangaben in WEZ +2. Es ist jetzt 15:55 Uhr.




Powered by vBulletin® Version 3.7.2 (Deutsch)
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
Aprilia-Forum, Aquaristik-Forum, Liebeskummer-Forum, Zierfisch-Forum, Geizkragen-Forum