PHP Socket

Aradiv

Well-known member
ID: 217591
L
20 April 2006
1.683
176
folgendes Problem

ich möchte über ein Socket mehrere Anfragen senden

bisher mache ich das über mehrere Sockets

Also
Socket öffnen
Anfrage senden
Anfrage verarbeiten
Socket schließen

Socket öffnen
Anfrage senden
Anfrage verarbeiten
Socket schließen

Socket öffnen
Anfrage senden
Anfrage verarbeiten
Socket schließen
Da es aber relativ unpraktisch ist X Sockets zu öffnen und zu schließen hab ich mir gedacht man könnte doch auch

Socket öffnen
Anfrage senden
Anfrage verarbeiten

Anfrage senden
Anfrage verarbeiten

Anfrage senden
Anfrage verarbeiten
Socket schließen
machen so hätte man nur 1 Socket geöffnet. Allerdings macht da wohl fsockopen nicht mit
beim 1. Request funktioniert noch alles normal
beim 2. Request bekomme ich genau 0 Daten zurück fwrite sendet seine 223 Zeichen aber mehr passiert beim 2. request nicht.

So kennt jemand von euch eine Möglichkeit in PHP eine Persistente Verbindung herzustellen?


So hier noch ein Beispielscript (test.php gibt einfach nur $_GET['c'] aus)
PHP:
<?php
$host='localhost';
$s=fsockopen($host, 80);
fwrite( $s, implode( chr( 10 ), $request = array(
            'POST /test.php?c=1 HTTP/1.0',
            'Host: ' . $host . '',
            'Referer: https://' . $host . '',
            'Cookie: ',
            'Content-Type: application/x-www-form-urlencoded',
            'Content-Length: 0',
            '',
            ''
        ) ) );
echo "request1<br >/";
while( !feof( $s ) ) {
    echo fread( $s, 1024 );
}
fwrite( $s, implode( chr( 10 ), $request = array(
            'POST /test.php?c=2 HTTP/1.0',
            'Host: ' . $host . '',
            'Referer: https://' . $host . '',
            'Cookie: ',
            'Content-Type: application/x-www-form-urlencoded',
            'Content-Length: 0',
            '',
            ''
        ) ) );
echo "<br />request2<br />";
while( !feof( $s ) ) {
    echo fread( $s, 1024 );
}
fclose($s);
?>

Ausgabe
request1<br >/HTTP/1.1 200 OK
Date: Mon, 05 Jul 2010 19:06:09 GMT
Server: Apache/2.2.14 (Ubuntu)
X-Powered-By: PHP/5.3.2-1ubuntu4.2
Vary: Accept-Encoding
Content-Length: 0
Connection: close
Content-Type: text/html; charset=iso-8859-1

<br />request2<br />

Aradiv
 
Zuletzt bearbeitet:
Ich lese jetzt den Socket aus bis zum erreichen von eof (socket_get_status liefert eof =1 )

allerding wird eof nicht wieder resettet.

Wenn ich bis unread_bytes=0 Lese sind das nur genau 1440 bytes

einzige Alternative die mir grade noch einfällt wäre das ganze komplett auf die socket Funktionen umzuschreiben.

aber wenn es einen weg mit fsockopen gibt nehm ich den auch gerne ;-)

Aradiv
 
Ich lese jetzt den Socket aus bis zum erreichen von eof (socket_get_status liefert eof =1 )

allerding wird eof nicht wieder resettet.

eof (End Of File) heißt, dass die Verbindung geschlossen wurde, du musst sie also erneut aufbauen, um Daten anfordern zu können.
 
genau das will ich ja nicht wie oben bereits geschrieben

jetzt hab ich versucht einfach so lange zu lesen bis ich nicht 1440 zeichen bekomme.
Ergebnis das 3. mal kommen 1169 Bytes zurück obwohl die Datei noch nicht vollständig empfangen wurde. Heißt diese äussert dreckige Lösung funktioniert auch nicht.
 
jetzt hab ich versucht einfach so lange zu lesen bis ich nicht 1440 zeichen bekomme.
Ergebnis das 3. mal kommen 1169 Bytes zurück obwohl die Datei noch nicht vollständig empfangen wurde. Heißt diese äussert dreckige Lösung funktioniert auch nicht.

woher weisst du, dass bei 1169 Bytes nicht alles empfangen wurde? 8O
Die Anzahl der Bytes sagen doch gar nichts aus, immerhin gibt es dafür Protkolle an die du dich halten musst.
Ein Webserver muss sich natürlich nicht an den KeepAlive-Hinweis halten, tut es also meistens.

Am besten postet du deinen Beispielcode hier inkl. dem Server und man kann dir helfen deinen Fehler zu suchen, ist bestimmt nur ein Implementierungsfehler.

Edit: Hast du wenigstens schonmal versucht, dich an das HTTP-Protokoll zu halten? In den Headern steht ein Contentlength-Header der die angibt wieviele Bytes der Content enthält, man liest nie einfach bis zum Ende oder eine Anzahl an x Bytes bei HTTP.
 
Tu ich ja ;-)

aber beim Auslesen sind die Daten eben in Blöcken die meisten sind zwar 1440 Byte groß aber eben nicht alle ausserdem kann das ja nicht die Lösung sein.
hier mal der Code mit dem Ausgelesen wird

PHP:
fwrite( $this->socket, implode( chr( 10 ), $request = array(
            'POST /dieseite.php HTTP/1.1',
            'Host: ' . $this->host . '',
            'Referer: https://' . $this->host . '',
            'Cookie: ',
            'Content-Type: application/x-www-form-urlencoded',
            'Content-Length: ' . strlen( $params = 'u_id=' . (int) $id . '&u_pwd='. $pw .'' ) . '',
            'Keep-Alive:300',
            'Connection:Keep-Alive',
            '',
            $params,
        ) ) );
        $content = '';
        $status=socket_get_status($this->socket);
        while(strlen($read)==1440 || strlen($content)==0){
            $read="";
            while(strlen($read)==0 || $status['unread_bytes']>0){
                if($status['unread_bytes']>0 && $status['unread_bytes']<255){
                    $read.=fread($this->socket, $status['unread_bytes']);
                }else{
                    $read.=fread( $this->socket , 255);
                }
                $status=socket_get_status($this->socket);
            }
            $content.=$read;
        }
Aradiv

PS zu Content-Length ja hab ich versucht der server liefert diesen Header
HTTP/1.1 200 OK
Server: nginx/0.6.35
Date: Wed, 07 Jul 2010 17:02:17 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: keep-alive
X-Powered-By: PHP/5.2.6-1+lenny4
Set-Cookie: PHPSESSID=17057055114f552c26fd5274261110e1; expires=Wed, 14 Jul 2010 17:02:17 GMT; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Set-Cookie: PHPSESSID=0713830153bdb4b0ff4063a0f3284d8b; expires=Wed, 14 Jul 2010 17:02:17 GMT; path=/
Vary: Accept-Encoding
Also leider keine Angabe vom Server :ugly:

Das mit Content-length war meine erste Idee so hatte ich es auch erst bis ich gemerkt habe das manche Server das wohl nicht senden

Bis wohin soll ich bei diesem Header also Lesen?