php.de

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

PHP-Fortgeschrittene Arbeiten mit PHP ohne Einschränkungen

Antwort
 
LinkBack Themen-Optionen
Alt 01.04.2011, 13:22  
Neuer Benutzer
 
Registriert seit: 17.07.2009
Beiträge: 18
PHP-Kenntnisse:
Fortgeschritten
Remon befindet sich auf einem aufstrebenden Ast
Standard socket_read() im blocking modus

Guten Tag liebe PHPler,

ich habe eine kleine MVC Implementation mit integriertem HTTP Server geschrieben. Diese funktioniert soweit. Das Problem besteht darin den Status des Sockets abzufragen. In POST Requests die nicht mit einem identifizierbarem Ende aufhören kann ich so nicht auslesen ohne vorher ihre Bytelänge zu kennen.

Das Script wartet solange bis Daten nach gesendet werden, dies wird aber nicht geschehen.

PHP-Code:
<?php

class Server_Socket {
    private 
$socket;
    private 
$response;
    private 
$request;
    private 
$disp;
    public 
$dbs;
    
    public function 
__construct() {
        
$this->socket socket_create_listenServer_Config::PORT );
        
socket_set_nonblock$this->socket );
        
$this->dbs = new Server_Pool_Database;
        
        
Server_Cron::init();
        
        
//Alle Crons einrichten
        
Server_Cron::add( array( $this->dbs"check" ), ( 60 ) );
        
Server_Cron::add"Server_Statistic::createShot", ( 15 60 ) );
        
Server_Cron::add"Server_Session::checkSessions"60 );
        
        if( 
PHP_OS != 'WINNT' ) {
            
            
$fork = new Server_ForkServer_Config::CHILDS$this );    
        }
        
        else {
            
$this->listen();    
        }
    }
    
    public function 
listen() {
        
$this->response = new Server_Http_Response;
        
$this->request = new Server_Http_Request;
        
$this->disp = new MVC_Dispatcher;
        
        if( 
PHP_OS == 'WINNT' ) {
            while( 
) {
                
Server_Cron::handle( );

                while( 
$conn = @socket_accept$this->socket ) ) {
                    
socket_set_block$conn );
                    
$this->handleRequest$conn );    
                }
            }
        }
        
        else {
            while( 
) {
                while( 
$conn = @socket_accept$this->socket ) ) {
                    
socket_set_block$conn );
                    
$this->handleRequest$conn );    
                }
            }
        }
    }
    
    public static function 
readFromSocket$conn$end = array( "\n" => "" ) ) {
        
$ret "";
        
        do {
            
$read socket_read$conn);
            
$ret .= $read;
        } while( !isset( 
$end[$read] ) );
        
        return 
$ret;
    }
    
    private function 
handleRequest$conn ) {
        try {
            
$start microtimetrue );
            
            
$this->request->reset();
            
$this->request->newRequest$conn );
        
            
$this->response->reset();
            
$this->response->httpCode200 );
            
            if( !isset( 
$this->request->path['extension'] ) || in_array$this->request->path['extension'], $this->disp->supported() ) ) {
                
$this->disp->root$this->request$this->response );    
                
$this->response->send$conn );
            }            
            
            elseif( isset( 
Server_Mime::$mime[$this->request->path['extension']] ) ) {
                
$this->response->setHeader"Content-Type"Server_Mime::$mime[$this->request->path['extension']] );
                
$this->response->sendFile"www/"$this->request->conf['main']['document-root'] ."/static/"$this->request->url['path'], $conn );    
            }
            
            else {
                
$this->response->httpCode404 );
                
$this->response->setContent'File not Found!' );
                
$this->response->send$conn );
              }
        }
        
        catch( 
Server_Http_Exception $e ) {
            
$this->response->reset();
            
$this->response->httpCode$e->getCode() );
            
$this->response->setContent$e->getMessage() );    
            
$this->response->send$conn );
        }
    }
}

?>
Und zwar geht es hier um die statische funktion readFromSocket die bis zu einem \n ( Zeilenumbruch liest ) und dann aufhört und den gelesenden String zurück gibt. Das Problem ist wie gesagt das beim letzten lesen kein Zeilenumbruch ist und er unendlich ( bzw. timeout ) auf ein weiteres Byte wartet.
Remon ist offline   Mit Zitat antworten
Sponsor Mitteilung
PHP Code Flüsterer

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

Alt 01.04.2011, 14:31  
Erfahrener Benutzer
 
Registriert seit: 07.09.2009
Beiträge: 6.019
PHP-Kenntnisse:
Fortgeschritten
lstegelitz hat eine strahlende Zukunftlstegelitz hat eine strahlende Zukunftlstegelitz hat eine strahlende Zukunftlstegelitz hat eine strahlende Zukunftlstegelitz hat eine strahlende Zukunftlstegelitz hat eine strahlende Zukunftlstegelitz hat eine strahlende Zukunftlstegelitz hat eine strahlende Zukunftlstegelitz hat eine strahlende Zukunftlstegelitz hat eine strahlende Zukunftlstegelitz hat eine strahlende Zukunft
Standard

Du brauchst ein non-blocking socket...

edit: warum ist bei dir \n ein Zeichen dafür, das die Übertragung endet? Auf Stream-Ebene muss jedes Byte durchgehen können, die Contentlänge bestimmt, wieviele Daten gelesen werden müssen.
__________________
Über 90% aller Gewaltverbrechen passieren innerhalb von 24 Stunden nach dem Konsum von Brot.
lstegelitz ist offline   Mit Zitat antworten
Alt 01.04.2011, 20:57  
Neuer Benutzer
 
Registriert seit: 17.07.2009
Beiträge: 18
PHP-Kenntnisse:
Fortgeschritten
Remon befindet sich auf einem aufstrebenden Ast
Standard

Es gibt zum Beispiel beim Header lesen nach jedem Header einen Zeilenumbruch. Damit ich jeden Header einzelnd lesen kann gibt mir die funktion nur bis zum nächsten Zeilenumbruch den String zurück.

Das mit non block hatte ich auch schon. Das Problem dabei ist das der schreibbuffer nicht schnell genug ist und geschriebende Bytes nicht sendet.
Remon ist offline   Mit Zitat antworten
Alt 04.04.2011, 11:55  
Benutzer
 
Registriert seit: 25.01.2011
Beiträge: 66
PHP-Kenntnisse:
Fortgeschritten
Renner befindet sich auf einem aufstrebenden Ast
Standard

RFC2616, 4.4 Message Length ?
Renner ist offline   Mit Zitat antworten
Alt 05.04.2011, 10:49  
Erfahrener Benutzer
 
Registriert seit: 07.09.2009
Beiträge: 6.019
PHP-Kenntnisse:
Fortgeschritten
lstegelitz hat eine strahlende Zukunftlstegelitz hat eine strahlende Zukunftlstegelitz hat eine strahlende Zukunftlstegelitz hat eine strahlende Zukunftlstegelitz hat eine strahlende Zukunftlstegelitz hat eine strahlende Zukunftlstegelitz hat eine strahlende Zukunftlstegelitz hat eine strahlende Zukunftlstegelitz hat eine strahlende Zukunftlstegelitz hat eine strahlende Zukunftlstegelitz hat eine strahlende Zukunft
Standard

Zitat:
Zitat von Remon Beitrag anzeigen
Das mit non block hatte ich auch schon. Das Problem dabei ist das der schreibbuffer nicht schnell genug ist und geschriebende Bytes nicht sendet.
Dann hast du es vlt. falsch implementiert. Hast du die Hinweise zu socket_write() beachtet?
Zitat:
socket_write() does not necessarily write all bytes from the given buffer. It's valid that, depending on the network buffers etc., only a certain amount of data, even one byte, is written though your buffer is greater. You have to watch out so you don't unintentionally forget to transmit the rest of your data.
Du kannst jedenfalls nicht den gleichen Code verwenden, wie bei sequentiellem Versenden. Non-Blocking heisst, alle Funktionen kehren *sofort* wieder zurück und geben Hinweise darauf, was passieren könnte, wenn die Voraussetzungen nicht erfüllt sind (accept() ohne Clientanfrage liefert z.B. WSAWOULDBLOCK, ein Hinweis darauf, das bei einem blocking-socket dieser blockieren würde um auf einen Client zu warten...)

Das heisst, man muss anders an die Sache rangehen und immer vorher prüfen (peek) was passieren würde. Beim Senden musst du immer noch abfragen, ob auch alle Daten gesendet wurden, die du bereitgestellt hast und eventuell "nachliefern"... asynchrone Operationen verlangen asynchrones Handeln, du musst dann selber machen, was dir im blocking modus der Netzwerktreiber abnimmt (Pufferung von Daten, Häppchenweises Senden o. Empfangen).
__________________
Über 90% aller Gewaltverbrechen passieren innerhalb von 24 Stunden nach dem Konsum von Brot.
lstegelitz ist offline   Mit Zitat antworten
Antwort


Themen-Optionen


Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
[Erledigt] Verständnis non blocking stream McSodbrenner PHP-Fortgeschrittene 4 13.03.2011 13:49
[Erledigt] Standardkonformen Modus erzwingen Dark Guardian HTML, Usability und Barrierefreiheit 2 10.02.2011 16:48
[Erledigt] IE Quirks Modus und Menu chunky HTML, Usability und Barrierefreiheit 9 10.02.2010 16:27
Rausfinden ob Browser im inkognito modus roest PHP Tipps 2009 3 29.07.2009 03:14
fopen im Modus "a" und der Dateizeiger Mati_ PHP-Fortgeschrittene 10 02.07.2009 22:48
[Erledigt] PHP - Modus Statistk dsmcg PHP Tipps 2009 11 16.06.2009 20:36
[Erledigt] Voting mit IP blocking PHP Tipps 2006 8 20.02.2006 23:07
[Erledigt] PHP Safe Modus deaktivieren ! PHP-Fortgeschrittene 8 27.02.2005 14:21
socket / non blocking / socket_accept Problem PHP Tipps 2004 0 08.06.2004 16:08

Besucher kamen über folgende Suchanfragen bei Google auf diese Seite
php socket_read, php socket_read blocking, php socket_read blocks, php socket_read timeout, socket_read timeout, socket_read blockt nicht php, socket_read php_normal, socket_read php_normal_read blocking, fork socket_read, php socket_read not working, php socket_read blocks write, while socket_read php, php socket_read byteweise einlesen, try catch socket_read php, socket_read wartet nicht, php_normal_read blocking, blocking modus php, socket_read blocks, php normal read blocking, php socket_read block

Alle Zeitangaben in WEZ +2. Es ist jetzt 05:41 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