【技术产品】PHP fsockopen函数详解

时间:2020-03-19 10:35:21 来源:

【摘要】 对于初入门的php学习者肯定会有很多问题,今天考比过小编为大家整理了关于【技术产品】PHP fsockopen函数详解的信息,希望可以帮助到大家。下面就让我们一起来看下【技术产品】PHP fsockopen函数详解的具体内容吧!

PHP fsockopen是一个功能比较强大的函数。我们在这篇文章中将会对这个函数做一个具体的介绍,希望对大家有所帮助。记得以前的B2C网站就是通过这个函数实现前台和订单处理系统的交互。

PHP fsockopen函数说明:

语法:

resource fsockopen ( string $hostname [, int KaTeX parse error: Expected 'EOF', got '&' at position 20: … = -1 [, int &̲errno [, string &$errstr [, float $timeout = ini_get(“default_socket_timeout”) ]]]] )

开启PHP fsockopen这个函数

PHP fsockopen需要 PHP.ini 中 allow_url_fopen 选项开启。

allow_url_fopen = On

参数:

hostname:如果安装了OpenSSL,那么你也许应该在你的主机名地址前面添加访问协议ssl://或者是tls://,从而可以使用基于TCP/IP协议的SSL或者TLS的客户端连接到远程主机。

port:端口号。如果对该参数传一个-1,则表示不使用端口,例如unix://。

errno:如果errno的返回值为0,而且这个函数的返回值为 FALSE ,那么这表明该错误发生在套接字连接(connect())调用之前,导致连接失败的原因最大的可能是初始化套接字的时候发生了错误。

errstr:错误信息将以字符串的信息返回。

timeout:设置连接的时限,单位为秒。

返回值:

fsockopen() 将返回一个文件句柄,之后可以被其他文件类函数调用(例如: fgets() , fgetss() , fwrite() , fclose() 还有 feof() )。如果调用失败,将返回 FALSE 。

php fsockopen使用案例

1、fsockopen 来模拟生成 HTTP 连接

<?php
    $fp = fsockopen("127.0.0.1",80,$errno,$errstr,30);
    if(!$fp){
        echo "$errstr ($errno)<br />\n";
    }else{
        $out = "GET / HTTP/1.1\r\n";
        $out .= "Host: 127.0.0.1\r\n";
        $out .= "Connection: Close\r\n\r\n";
        fwrite($fp,$out);
        $content = '';
        while(!feof($fp)){
            $content .= fgets($fp,128);
        }
        echo $content;
        fclose($fp);
    }
?>

运行结果:

2、PHP fsockopen模拟POST/GET方法

fsockopen除了像上面实例模拟生成 HTTP 连接之外,还能实现很多功能,比如模拟post 和 get 传送数据的方法。
get :

<?php
$url = "http://localhost/test2.php?site=www.tbrer.com";
print_r(parse_url($url));// 解析 URL,返回其组成部分

/* get提交 */
sock_get($url,'user=gonn');

// fsocket模拟get提交
function sock_get($url,$query){
    $data = array(
        'foo' => 'bar',
        'baz' => 'boom',
        'site' => 'www.tbrer.com',
        'name' => 'nowa magic'
    );

    $query_str = http_build_query($data);// http_build_query()函数的作用是使用给出的关联(或下标)数组生成一个经过 URL-encode 的请求字符串

    $info = parse_url($url);
    $fp = fsockopen($info["host"],80,$errno,$errstr,30);
    $head = "GET " . $info['path'] . '?' . $query_str . " HTTP/1.0\r\n";
    $head .= "Host: " . $info['host'] . "\r\n";
    $head .= "\r\n";
    $write = fputs($fp,$head);
    while(!feof($fp)){
        $line = fread($fp,4096);
        echo $line;
    }
}
?>

post :

<?php
$url = "http://localhost/test2.php?site=www.tbrer.com";
print_r(parse_url($url));// 解析 URL,返回其组成部分

/* get提交 */
sock_post($url,'user=gonn');

// fsocket模拟get提交
function sock_post($url,$query){
    $info = parse_url($url);
    $fp = fsockopen($info["host"],80,$errno,$errstr,30);
    $head = "POST " . $info['path'] . "?" . $info["query"] . " HTTP/1.0\r\n";
    $head .= "Host: " . $info['host'] . "\r\n";
    $head .= "Referer: http://" . $info['host'] . $info['path'] . "\r\n";
    $head .= "Content-type: application/x-www-form-urlencoded\r\n";
    $head .= "Content-Length: ". strlen(trim($query)) . "\r\n";
    $head .= "\r\n";
    $head  .= trim($query);
    $write = fputs($fp,$head);
    while(!feof($fp)){
        $line = fread($fp,4096);
        echo $line;
    }
}
?>

接收页面 test2.php 的代码为:

<?php
    $data = $_REQUEST;

    echo '<pre>';
    print_r($data);
    echo '</pre>';
?>

3、fsockopen以Socket方式模拟HTTP下载文件

<?php
    /* 
        *   Socket 模拟HTTP协议传输文件
        *   Http是应用层协议使用80端口
    */
    $hostname = '127.0.0.1';
    $port = '80';

    // 建立连接
    $fp = fsockopen($hostname,$port,$errno,$errstr);
    stream_set_blocking($fp,true);
    if(!$fp){
        echo "$errno : $errstr<br />";
    }else{
        // 发送一个HTTP请求信息头
        $request_header = "GET /aaa.txt";

        // 起始行
        // 头域 
        $request_header .= "Host: $hostname\n";
        
        // 再一个回车换行表示头信息结束
        $request_header .= "\n";

        // 发送请求到服务器
        fputs($fp,$request_header);

        // 接受响应
        $fp2 = fopen('aaa.txt','w');

        while(!feof($fp)){
            $line = fputs($fp2,fgets($fp,128));
            echo $line;
        }

        // 关闭
        fclose($fp2);
        fclose($fp);
    }
?>

执行程序,你会发现在这个程序文件的同级目录就会出现那个你需要下载的文件了。

这实质上是 Socket 模拟HTTP协议传输文件。同时还要注意一下 PHP 的超时限制,这里设置我 PHP 服务器超时为无限才能正确下载,否则可能下载不全 PHP 程序就停止了。

注意:

bool stream_set_blocking ( resource $stream , int $mode )

为 stream 设置阻塞或者阻塞模。

此函数适用于支持非阻塞模式的任何资源流(常规文件,套接字资源流等)。

参数

stream:资源流。

mode:如果 mode 为0,资源流将会被转换为非阻塞模式;如果是1,资源流将会被转换为阻塞模式。 该参数的设置将会影响到像 fgets() 和 fread() 这样的函数从资源流里读取数据。 在非阻塞模式下,调用 fgets() 总是会立即返回;而在阻塞模式下,将会一直等到从资源流里面获取到数据才能返回。

返回值

成功时返回 TRUE, 或者在失败时返回 FALSE。

4、使用 fsockopen 伪造来路

<?php
$host = "127.0.0.1"; //你要访问的域名
$ip = '127.0.0.1';
$target = "/test2.php"; //你要访问的页面地址
$referer = "http://www.tbrer.com/"; //伪造来路页面
//$fp = fsockopen($host, 80, $errno, $errstr, 30);
$fp = fsockopen($ip, 80, $errno, $errstr, 30);
if(!$fp)
{
    echo "$errstr($errno)<br />\n";
}
else
{
	$end = "\r\n";
    $out = "GET $target HTTP/1.1$end";
	$out .= "Host: $ip$end";
	$out .= "Referer: $referer$end";
	$out .= "Connection: Close$end";
	$out .= "$end";
    fwrite($fp, $out);
    while(!feof($fp))
    {
        echo fgets($fp, 1024);
    }
    fclose($fp);
}
?>

test2.php 的代码为:

<?php
    $data = $_REQUEST;

    echo '<pre>';
    print_r($data);
    echo '</pre>';
?>

可以看到 HTTP_REFERER 的值为 http://www.tribrer.com/,即来路已经伪造成功。

以上就是考比过小编为大家整理的【技术产品】PHP fsockopen函数详解内容,希望可以帮助到你,如果你还有更多关于php的问题,请持续关注考比过php频道,小编会持续为大家分享关于php方面的知识!

上一篇      下一篇
PHP培训相关推荐 更多>>
【技术产品】PHP代码加密的几种方法介绍 【技术产品】php链式操作的实现 【技术产品】PHP底层分析之关于强制分裂 【技术产品】PHP中设置session过期的方法 【技术产品】PHP实现统计在线人数的方法 【技术产品】PHP一些实用小技巧 【技术产品】php开启和关闭错误提示的方法介绍 【技术产品】PHP终止脚本执行的方法介绍
PHP培训热点专题 更多>>
热点问答
国家公务员考试年龄限制是多少 公务员国考和省考考试内容有什么区别 函授大专学历能不能考公务员 国家公务员考试考点能自己选择吗 新闻学专业能报考2022年公务员考试吗 什么是联合培养研究生 什么是破格录取研究生 什么人不适合读研 研究生报名户口所在地填什么 研究生结业和毕业有什么区别
网站首页 网站地图 返回顶部
考必过移动版 https://m.kaobiguo.net