Home  >  Article  >  Backend Development  >  Detailed explanation of PHP fsockopen function

Detailed explanation of PHP fsockopen function

尚
forward
2020-03-17 09:49:387249browse

Detailed explanation of PHP fsockopen function

PHP fsockopen is a relatively powerful function. In this article, we will give a detailed introduction to this function, hoping it will be helpful to everyone. I remember that previous B2C websites used this function to realize the interaction between the front desk and the order processing system.

PHP fsockopen function description:

Syntax:

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”) ]]]] )

Enable PHP fsockopen function

PHP fsockopen requires the allow_url_fopen option in PHP.ini to be turned on.

allow_url_fopen = On

Parameters:

hostname: If OpenSSL is installed, you may want to add the access protocol ssl:// or tls:// in front of your hostname address so that you can use An SSL or TLS client based on the TCP/IP protocol connects to a remote host.

port: port number. If -1 is passed to this parameter, it means that the port is not used, such as unix://.

errno: If the return value of errno is 0, and the return value of this function is FALSE, then this indicates that the error occurred before the socket connection (connect()) call, which is the biggest cause of the connection failure. It is possible that an error occurred when initializing the socket.

errstr: The error message will be returned as a string.

timeout: Set the time limit for the connection, in seconds.

Return value:

fsockopen() will return a file handle, which can later be called by other file class functions (for example: fgets(), fgetss(), fwrite(), fclose() There is also feof()). If the call fails, FALSE will be returned.

php fsockopen use case

1. fsockopen to simulate generating HTTP connection

<?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 = &#39;&#39;;
        while(!feof($fp)){
            $content .= fgets($fp,128);
        }
        echo $content;
        fclose($fp);
    }
?>

Running results:

Detailed explanation of PHP fsockopen function

2. PHP fsockopen simulates the POST/GET method

In addition to simulating the generation of HTTP connections like the above example, fsockopen can also implement many functions, such as simulating the post and get methods of transmitting data.
get :

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

/* get提交 */
sock_get($url,&#39;user=gonn&#39;);

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

    $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[&#39;path&#39;] . &#39;?&#39; . $query_str . " HTTP/1.0\r\n";
    $head .= "Host: " . $info[&#39;host&#39;] . "\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,&#39;user=gonn&#39;);

// fsocket模拟get提交
function sock_post($url,$query){
    $info = parse_url($url);
    $fp = fsockopen($info["host"],80,$errno,$errstr,30);
    $head = "POST " . $info[&#39;path&#39;] . "?" . $info["query"] . " HTTP/1.0\r\n";
    $head .= "Host: " . $info[&#39;host&#39;] . "\r\n";
    $head .= "Referer: http://" . $info[&#39;host&#39;] . $info[&#39;path&#39;] . "\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;
    }
}
?>

The code for receiving page test2.php is:

<?php
    $data = $_REQUEST;

    echo &#39;<pre class="brush:php;toolbar:false">&#39;;
    print_r($data);
    echo &#39;
'; ?>

3. fsockopen simulates HTTP download files in Socket mode

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

    // 建立连接
    $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(&#39;aaa.txt&#39;,&#39;w&#39;);

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

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

Execute the program, and you will find that the file you need to download will appear in the directory at the same level as the program file.

This is essentially Socket simulating the HTTP protocol to transfer files. At the same time, pay attention to the timeout limit of PHP. Here, I set the timeout of my PHP server to unlimited to download correctly. Otherwise, the download may not be complete and the PHP program will stop.

Note:

bool stream_set_blocking (resource $stream, int $mode)

Set blocking or blocking mode for stream.

This function works with any resource stream that supports non-blocking mode (regular file, socket resource stream, etc.).

Parameters

stream: Resource stream.

mode: If mode is 0, the resource flow will be converted to non-blocking mode; if it is 1, the resource flow will be converted to blocking mode. The setting of this parameter will affect functions like fgets() and fread() that read data from resource streams. In non-blocking mode, calling fgets() will always return immediately; in blocking mode, it will wait until data is obtained from the resource stream before returning.

Return value

Returns TRUE on success, or FALSE on failure.

4. Use fsockopen to forge the source

<?php
$host = "127.0.0.1"; //你要访问的域名
$ip = &#39;127.0.0.1&#39;;
$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);
}
?>

The code of test2.php is:

<?php
    $data = $_REQUEST;

    echo &#39;<pre class="brush:php;toolbar:false">&#39;;
    print_r($data);
    echo &#39;
'; ?>

You can see that the value of HTTP_REFERER is http://www.tribrer.com /, that is, the origin has been forged successfully.

Related recommendations:

PHP video tutorial: https://www.php.cn/course/list/29/type/2.html

The above is the detailed content of Detailed explanation of PHP fsockopen function. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:csdn.net. If there is any infringement, please contact admin@php.cn delete