0

HTMLページと画像を取得するための基本的なスクリプトを作成しました。しかし、私は写真を取得している間、接続を維持したいと思います。
-テストスクリプトで行ったことは、Webサーバー上のアドレスを要求し続けました。しかし、それは機能しませんでした。
では、どうすればよいのでしょうか、それとも何を間違えたのでしょうか。

基本的なスクリプト:

function fetch( $server, $url, $port = 80, &$resp_head )
{
    if ( !$con = @fsockopen($server, $port, $error_number, $error_string, 30) ) return False;
    stream_set_timeout( $con, 8600 );

    // Reguest
    $qry_header = 'GET '.$url." HTTP/1.1\r\n";
    $qry_header .= 'Host: '.$server."\r\n";
    $qry_header .= 'User-Agent: Mihtyom; (+http://'.$_SERVER['HTTP_HOST']."/)\r\n";
    $qry_header .= "Accept: */*\r\n";           //google check the 3 "Accept"
    $qry_header .= "Accept-Language: *\r\n";
    $qry_header .= "Accept-Encoding: *\r\n";
    $qry_header .= "Connection: Close\r\n\r\n";
    fwrite( $con, $qry_header );

    $inheader = True;
    $data = '';
    while (!feof( $con ))
    {
        $line = fgets( $con );
        if (!$inheader)
        {
            $data .= $line;
            continue;
        }
        if ($line == "\n" || $line == "\r\n")
        {
            $inheader = False;
            continue;
        }
        $resp_head[] = trim($line);
    }

    fclose( $con );

    return $data;
}

テストスクリプト:

function fetch( $server, $urls, $port = 80, &$resp_head )
{
    if ( !$con = @fsockopen($server, $port, $error_number, $error_string, 30) ) return False;
    stream_set_timeout( $con, 8600 );

    $resp_head = array();
    $data = array();
    foreach ($urls as $key => $url)
    {
        $inheader = True;
        $data[$key] = '';

        // Reguest
        $qry_header = 'GET '.$url." HTTP/1.1\r\n";
        $qry_header .= 'Host: '.$server."\r\n";
        $qry_header .= 'User-Agent: Mihtyom; (+http://'.$_SERVER['HTTP_HOST']."/)\r\n";
        $qry_header .= "Accept: */*\r\n";           //google check the 3 "Accept"
        $qry_header .= "Accept-Language: *\r\n";
        $qry_header .= "Accept-Encoding: *\r\n";
        $qry_header .= "Connection: Close\r\n\r\n";
        fwrite( $con, $qry_header );

        while (!feof( $con ))
        {
            $line = fgets( $con );
            if (!$inheader)
            {
                $data[$key] .= $line;
                continue;
            }
            if ($line == "\n" || $line == "\r\n")
            {
                $inheader = False;
                continue;
            }
            $resp_head[$key][] = trim($line);
        }
    }
    fclose( $con );
    return $data;
}

新しいスクリプト(21-07-12 12:34):

function fetch( $server, $urls, $port = 80, &$resp_head )
{
    if ( !$con = @pfsockopen($server, $port, $error_number, $error_string, 30) ) return False;
    stream_set_timeout( $con, 8600 );

    $resp_head = array();
    $data = '';
    $i = count($urls);
    foreach ($urls as $key => $url )
    {
        $i--;

        // Reguest
        $qry_header = 'GET '.$url." HTTP/1.1\r\n";
        $qry_header .= 'Host: '.$server."\r\n";
        $qry_header .= 'User-Agent: Mihtyom; (+http://'.$_SERVER['HTTP_HOST']."/)\r\n";
        $qry_header .= "Accept: */*\r\n";
        $qry_header .= "Accept-Language: *\r\n";
        $qry_header .= "Connection: ".($i == 0 ? 'Close' : 'keep-alive')."\r\n\r\n";
        fwrite( $con, $qry_header );
    }

    while (!feof( $con ))
    {
        $line = fgets( $con );
        if ($line == "\r\n\r\n" || $line == "\n\n") break;
        $data .= $line;
    }
    fclose( $con );
    return $data;
}
4

1 に答える 1

1

HTTPヘッダーで指定Connection: Closeします。これは、基本的にサーバーに「この1つのファイルを渡して、すぐに接続を閉じます」と通知します。あなたは実際に接続を強制的に閉じています。

代わりに、を指定できますConnection: Keep-Alive。これは、TCPセッションを閉じないようにサーバーに(明示的に)指示して、別の要求に再利用できるようにします。

ただし、サーバーはいかなる場合でもこれを受け入れてはなりません。サーバーは要求を無視して、で応答する場合がありますConnection: Close。また、接続の各側はいつでも接続を閉じるか、(次の)ヘッダーでを介して反対側にそうするように指示することができConnection: Closeます。

正しく実装するにはConnection: Close、ループが最後のURLを処理するタイミングを指定する必要があります。

持続的接続の詳細については、HTTP 1.1 / RFC 2068セクション14.10HTTP 1.1 /RFC2616セクション19.6.2を参照してください。

于 2012-07-20T19:30:03.133 に答える