fsockopen与HTTP 1.1/HTTP 1.0

Posted 壁虎漫步.

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了fsockopen与HTTP 1.1/HTTP 1.0相关的知识,希望对你有一定的参考价值。

在前面的例子中,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的主要内容,如果未能解决你的问题,请参考以下文章

PHP fsockopen模拟POST/GET方法

Socket编程 之使用fsockopen()函数

socket_create 与 fsockopen php

fsockopen用feof读取http响应内容的一些问题

HTTP1.0 HTTP 1.1 HTTP 2.0主要区别

php fsockopen() 无法建立连接