2012-04-11 7 views
0

Ich bin auf ein dummes Problem läuft: Ich muss eine bestimmte Anzahl von Bytes erhalten, dann schließen Sie die Verbindung. Ich habe herausgefunden, dass ich die "Inhaltslänge" aus der Kopfzeile extrahieren kann, und benutze die Länge, um zu bestimmen, wie viele Bytes ich noch bekommen soll, bevor ich die Verbindung durchtrenne. Es scheint jedoch, dass ich einen Fehler gemacht habe. Es wird nur 40 Byte statt 2428 (wie es sollte). Vielleicht verwende ich fgets() nicht richtig? HierHTTP Response-> Erhalten eine genaue Anzahl von Bytes, dann Schließen der Verbindung

ist der Code:

private static function Send($URL, $Data) { 
      $server = parse_url($URL, PHP_URL_HOST); 
      $port = parse_url($URL, PHP_URL_PORT); 

      // If the parsing the port information fails, we will assume it's on a default port. 
      // As such, we'll set the port in the switch below. 
      if($port == null) { 
       switch(parse_url($URL, PHP_URL_SCHEME)) { 
        case "HTTP": 
         $port = 80; 
         break; 
        case "HTTPS": 
         $port = 443; 
         break; 

       } 
      } 

      // Check if we are using a proxy (debug configuration typically). 
      if(\HTTP\HTTPRequests::ProxyEnabled) { 
       $server = \HTTP\HTTPRequests::ProxyServer; 
       $port = \HTTP\HTTPRequests::ProxyPort; 
      } 



      // Open a connection to the server. 
      $connection = fsockopen($server, $port, $errno, $errstr); 
      if (!$connection) { 
       die("OMG Ponies!"); 
      } 
      echo "===========================================================<BR>"; 
      echo "Connection Open<BR>"; 
      echo "The Time is " . date("H:i:su", time()) . "<BR>"; 
      echo "Sending Request<BR>"; 

      fwrite($connection, $Data); 

      echo "Request Sent."; 
      echo "The Time is " . date("H:i:su", time()) . "<BR>"; 
      $responseheader = ""; 
      $responsebody = ""; 


      /* 
      \HTTP\HTTPRequests::$start = NULL; 
      \HTTP\HTTPRequests::$timeout = 10; 

      // @todo: Rewrite this. Should keep checking for '/r/n/r/n', then check for a content length header. If found, keep grabbing bytes, then close. If not, then close immediately. 
      while(!\HTTP\HTTPRequests::safe_feof($connection, \HTTP\HTTPRequests::$start) && (microtime(true) - \HTTP\HTTPRequests::$start) < \HTTP\HTTPRequests::$timeout) 
      { 
       $response .= fgets($connection); 
      } 
      */ 
      echo "Getting Response<BR>"; 
      echo "The Time is " . date("H:i:su", time()) . "<BR>"; 
      while(!feof($connection) && !(strlen(strstr($responseheader,"\r\n\r\n"))>0)) { 
       $responseheader .= fgets($connection); 
      } 

      echo "The Header is fully received at " . date("H:i:su", time()) . "<BR>"; 
      echo "Header (raw):" . "<BR>"; 
      echo "/////////////////////////////////////////////<BR>"; 
      echo $responseheader . "<BR>"; 
      echo "/////////////////////////////////////////////<BR>"; 

      if((strlen(strstr($responseheader,"Content-Length:"))>0)) { 
       $contentlength = ((int)(\Extract\Extract::GetContentLength($responseheader))); 
       //for($i = 0; $i < $contentlength; $i++) { 
        $responsebody .= fgets($connection, $contentlength); 
       //} 
       echo "The Body is fully received at " . date("H:i:su", time()) . "<BR>"; 
       echo "Body (raw):" . "<BR>"; 
       echo "{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}<BR>"; 
       echo $responsebody . "<BR>"; 
       echo "{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}<BR>"; 
       echo "<B>!Content length is " . strlen($responsebody) . ". It should be " . $contentlength . "!</B><BR>"; 
      } 

      echo "Response Received.<BR>"; 
      echo "The Time is " . date("H:i:su", time()) . "<BR>"; 
      fclose($connection); 

      echo "Connection Closed.<BR>"; 
      echo "The Time is " . date("H:i:su", time()) . "<BR>"; 
      echo "Exiting Send() method.<BR>"; 
      echo "===========================================================<BR>"; 
      echo "<BR>"; 

      return $responseheader . $responsebody; 
     } 

Und hier ist die Ausgabe:

=========================================================== 
Connection Open 
The Time is 15:57:29000000 
Sending Request 
Request Sent.The Time is 15:57:29000000 
Getting Response 
The Time is 15:57:29000000 
The Header is fully received at 15:57:29000000 
Header (raw): 
///////////////////////////////////////////// 
HTTP/1.1 207 Multi-Status Date: Wed, 11 Apr 2012 19:57:18 GMT Server: Apache/2.2.8 (Ubuntu) PHP/5.2.4-2ubuntu5.14 with Suhosin-Patch mod_ssl/2.2.8 OpenSSL/0.9.8g mod_wsgi/2.0 Python/2.5.2 mod_perl/2.0.3 Perl/v5.8.8 X-Powered-By: PHP/5.2.4-2ubuntu5.14 DAV: 1, 2, 3, access-control, calendar-access, calendar-schedule DAV: extended-mkcol, calendar-proxy, bind, addressbook, calendar-auto-schedule Content-Location: /davical/caldav.php/rwr26/home/ ETag: "8378ead7e628deafd91ec99dc180ad74" X-DAViCal-Version: DAViCal/0.9.9; DB/1.2.9 Content-Length: 2428 Keep-Alive: timeout=15, max=100 Connection: Keep-Alive Content-Type: text/xml; charset="utf-8" 
///////////////////////////////////////////// 
The Body is fully received at 15:57:29000000 
Body (raw): 
{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 

{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 
!Content length is 40. It should be 2428! 
Response Received. 
The Time is 15:57:29000000 
Connection Closed. 
The Time is 15:57:29000000 
Exiting Send() method. 
=========================================================== 

Warum bin ich es auf diese Weise zu tun? Anscheinend ist mir ein Timeout-Fehler aufgefallen, bei dem jede Verbindung für 30 Sekunden geöffnet bleibt (ja, 30 ganze Sekunden). Also habe ich diesen Code geschrieben, um die genaue Anzahl der Bytes zu erhalten, und dann schließen. Jede Hilfe wird sehr geschätzt.

+0

Verwenden Sie [Fiddler] (http://www.fiddler2.com/fiddler2/), um zu sehen, was mit Ihren HTTP-Anfragen passiert. Was Sie tun, entspricht nicht genau den Standards des HTTP-Protokolls, und von was es klingt, ist all diese Arbeit nur so, dass Sie ein Problem (30-Sekunden-Verbindung) umgehen können, um es nicht wirklich zu lösen. Vielleicht sollten Sie lieber eine Frage zu Ihrem ursprünglichen Problem stellen, nicht zu Ihrer Problemumgehung. – qJake

+0

Was sind die versteckten 40 Zeichen - sind das wirklich alle "Leerzeichen" oder versteckte Tags? Antwort ist eine XML-Antwort - aka Tags - überprüfen Sie den Quellcode und Post kann helfen. – SinisterRainbow

Antwort

0

Ich habe die Inhaltszeile "$ responsebody. = Fgets ($ verbindung, $ contentlength);" zu "$ responsebody. = stream_get_line ($ verbindung, $ contentlength);". Das Ding ist jetzt schnell böse und funktioniert.

Verwandte Themen