5

PHPでSSL/TLS接続を使用して大量のデータを送信しようとしています。データチャンクがそれほど大きくない場合、またはTLSを使用していない場合でも、必要なもの(2MiB付近)の場合、fwrite関数は警告を表示します。

警告:fwrite():コード1でSSL操作が失敗しましたOpenSSLエラーメッセージ:エラー:1409F07F:SSLルーチン:SSL3_WRITE_PENDING:不正な書き込みの再試行

クライアントを接続するために使用している関連コード:

$cntxt = stream_context_create(array('ssl' => array('local_cert' => 'certificate.pem')));
$server = stream_socket_server('tls://127.0.0.1:8080', $errno, $errstr, STREAM_SERVER_BIND|STREAM_SERVER_LISTEN, $cntxt);

// Wait for client connection //

$client = stream_socket_accept($server);
// Use non-blocking socket to allow answering many clients at a time
stream_set_blocking($client, 0);
$clients[] = $client;

データを送信するとき、それはバッファに追加され、時々、この関数はクライアントとリンクされたバッファごとに呼び出されます。

function trySend($client, &$buffer) {
    if (strlen($buffer)) {
        $len = fwrite($client, $buffer);
        $buffer = substr($buffer, $len);
    }
}

私が言ったように、私のコードは少量のデータまたは通常の(非TLS)接続で機能します。このエラーを検索して、http ://www.openssl.org/docs/ssl/SSL_write.htmlを見つけました:

SSL_write()は、長さnumのbufの完全な内容が書き込まれた場合にのみ、成功して戻ります。このデフォルトの動作は、SSL_CTX_set_mode(3)のSSL_MODE_ENABLE_PARTIAL_WRITEオプションを使用して変更できます。このフラグが設定されている場合、部分的な書き込みが正常に完了すると、SSL_write()も成功して戻ります。この場合、SSL_write()操作は完了したと見なされます。バイトが送信され、新しいバッファ(すでに送信されたバイトが削除された状態)を使用した新しいSSL_write()操作を開始する必要があります。部分的な書き込みは、メッセージブロックのサイズ(SSLv3 / TLSv1の場合は16kB)で実行されます。

しかし、PHPでこれを行うにはどうすればよいですか?

助けていただければ幸いです:)

4

2 に答える 2

2

fwrite() に渡される文字列の長さを 8192 に制限することで、この問題を回避できることがわかりました。これにより、fwrite() の警告が防止されます。

したがって、あなたの例のコードでは、substr() 呼び出しを次のように変更してみます。

$buffer = substr($buffer, $len, 8192);
于 2013-06-11T13:45:28.723 に答える
-2

解決策は次のとおりです。

$msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;
try {                           
$result = fwrite($fp, $msg, strlen($msg));
}
catch (Exception $ex) {
sleep(1); //sleep for 5 seconds
$result = fwrite($fp, $msg, strlen($msg));
}
于 2016-04-29T13:53:24.990 に答える