0

次の(簡略化された)コードがあります。

function curl_request_async($url, $params)
{
    foreach ($params as $key => $val) {
        $post_params[] = $key.'='.urlencode($val);
    }
    $post_string = implode('&', $post_params);

    $parts=parse_url($url);

    $fp = fsockopen($parts['host'],
        isset($parts['port'])?$parts['port']:80,
        $errno, $errstr, 30);
    fwrite($fp, "$type ".$parts['path']." HTTP/1.1\r\n");
    fwrite($fp, "Host: ".$parts['host']."\r\n");
    fwrite($fp, "Content-Type: application/x-www-form-urlencoded\r\n");
    fwrite($fp, "Content-Length: ".strlen($post_string)."\r\n");
    fwrite($fp, "Connection: Close\r\n\r\n");

    $bytes_written = fwrite($fp, $post_string);
    var_dump($bytes_written, strlen($post_string));
    // fread($fp, 1);
    // fflush($fp);
    fclose($fp);
}

このコードの問題は、要求が呼び出されたサーバーに到達したという証拠が見つからなかったことです。この行は をvar_dump($bytes_written, strlen($post_string));出力int(493) int(493)したため、すべてのデータを受信したはずですが、受信していません。

コメントを外すfread($fp, 1);と問題なく動作します。それは有効な解決策かもしれませんが、意味がないようです。もっと良い方法があるはずです!

私の質問は 2 つあります。なぜ はfread($fp, 1);私の問題を解決し、より良い解決策があるのでしょうか?

4

2 に答える 2

1

あなたの問題はおそらく、サーバー コードを PHP で記述し、デフォルトで ignore_user_abort=true を設定していないことです ( http://php.net/manual/en/misc.configuration.php#ini.ignore-user-abortを参照) 。 、したがって、接続を閉じると、サーバーはphpコードの実行を停止するため、 fread(fp,1) 問題を修正します-phpが応答の書き込みを開始する前に接続を閉じないでください

このコードを使用してサーバーを作成し、実際に接続しているかどうかをテストできます-

<?php 
error_reporting(E_ALL);
ini_set('display_errors',1);
$sck=socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
if($sck===FALSE){
    die('socket_create failed!');
}
if(!socket_set_block($sck)){
    die("socket_set_block failed!");
}
if(!socket_bind($sck, '0.0.0.0',1337)){
    die("FAILED to bind to port 1337");
}
if(!socket_listen($sck,0)){
    die("socket_listen failed!");
}
$fullFile='';
while((print('listening for connections!'.PHP_EOL)) && false!==($conn=socket_accept($sck))){
    echo "new connection!".PHP_EOL;
    echo "generating crypto iv..";

    while(false!==($buffi=socket_recv($conn,$buff,1024,MSG_WAITALL))){
        if($buffi===0){
            break;//socket_recv's way of
            //saying that the connection closed,
            //apparently. the docs say it should return
            // false, but it doesn't, it just infinitely returns int(0).
            // at least on windows 7 x64 sp1.
        }
        $fullFile.=$buff;
        echo "recieved ".strlen($fullFile)." bytes...".PHP_EOL;
        $buff='';//do i need to clear it? or wiill recv do it for me?
    }
    echo "all bytes recieved (i guess, todo, socket_last_error confirm).";
    echo PHP_EOL;var_dump($fullFule);
    echo "done!".PHP_EOL;
}

die("should never reach this code...");

http://127.0.0.1:1337に netcat スタイルのサーバーを作成します。

于 2016-03-12T23:14:06.793 に答える