1. 程式人生 > >fsockopen與HTTP 1.1/HTTP 1.0

fsockopen與HTTP 1.1/HTTP 1.0

fwrite 詳細 odi com 詳細介紹 區別 connect func 阻塞

在前面的例子中,HTTP請求信息頭有些指定了 HTTP 1.1,有些指定了 HTTP/1.0,有些又沒有指定,那麽他們之間有什麽區別呢?

關於HTTP 1.1與HTTP 1.0的一些基本情況,可以參考下 HTTP 1.1的詳細介紹 。

我們先來看一下 fsockopen 不指定 HTTP 的情況:

function asyn_sendmail()
{
    $ip = ‘121.199.24.143‘;
    $url = ‘/php/sock.php‘;
    $fp = fsockopen($ip, 80, $errno, $errstr, 5);
    if (!$fp)
    {
        
echo "$errstr ($errno)<br />\n"; } $end = "\r\n"; $input = "GET $url$end"; $input.="$end"; fputs($fp, $input); $html = ‘‘; while (!feof($fp)) { $html.=fgets($fp); } fclose($fp); writelog($html); echo $html; } function writelog($message) {
$path = ‘F:\log2.txt‘; $handler = fopen($path, ‘w+b‘); if ($handler) { $success = fwrite($handler, $message); fclose($handler); } } asyn_sendmail();

sock.php:

<?php
    echo "Welcome to NowaMagic";
?> 

程序輸出:

Welcome to NowaMagic

log2.txt 內容也是:

Welcome to NowaMagic

那些接下來再看看在標頭加上 HTTP 1.1 的程序:

function asyn_sendmail()
{
    $ip = ‘121.199.24.143‘;
    $url = ‘/php/sock.php‘;
    $fp = fsockopen($ip, 80, $errno, $errstr, 5);
    if (!$fp)
    {
        echo "$errstr ($errno)<br />\n";
    }

    $end = "\r\n";
    $input = "GET $url HTTP/1.1$end";
    //如果不加下面這一句,會返回一個http400錯誤       
    $input.="Host: $ip$end";    
    //如果不加下面這一句,請求會阻塞很久      
    $input.="Connection: Close$end";     $input.="$end";
    fputs($fp, $input);
    $html = ‘‘;
    while (!feof($fp))
    {
        $html.=fgets($fp);
    }
    fclose($fp);
    writelog($html);
    echo $html;
}

function writelog($message)
{
    $path = ‘F:\log.txt‘;
    $handler = fopen($path, ‘w+b‘);
    if ($handler)
    {
        $success = fwrite($handler, $message);
        fclose($handler);
    }
}
asyn_sendmail();

程序輸出:

HTTP/1.1 200 OK
Date: Fri, 07 Feb 2014 13:50:14 GMT
Server: Apache/2.2.3 (CentOS)
X-Powered-By: PHP/5.3.3
Vary: Accept-Encoding
Content-Length: 21
Connection: close
Content-Type: text/html; charset=UTF-8

Welcome to NowaMagic 

留意到註釋:

//如果不加下面這一句,請求會阻塞很久      
$input.="Connection: Close$end";     $input.="$end";

原因是什麽呢? 可以參考 fsockopen用feof讀取http響應內容的一些問題。

//如果不加下面這一句,會返回一個http400錯誤       
$input.="Host: $ip$end";    

報400錯誤:

HTTP/1.1 400 Bad Request
Date: Fri, 07 Feb 2014 13:54:57 GMT
Server: Apache/2.2.3 (CentOS)
Content-Length: 305
Connection: close
Content-Type: text/html; charset=iso-8859-1

使用http1.1連接,要加上Host請求表頭。

小結:

  • HTTP 1.0, Apache Web 服務器中 $input.="Connection: Close$end"; 與 $input.="Connection: Close$end" 可都不需要。
  • HTTP 1.0, Nginx Web 服務器中 $input.="Connection: Close$end"; 與 $input.="Connection: Close$end" 都必需。
  • HTTP 1.1, Apache Web 服務器中 $input.="Connection: Close$end"; 必須要,$input.="Connection: Close$end" 可不用。
  • HTTP 1.1, Nginx Web 服務器中 $input.="Connection: Close$end"; 與 $input.="Connection: Close$end" 都必需。

fsockopen與HTTP 1.1/HTTP 1.0