1. ホーム
  2. php

[解決済み] CURL ERROR。Recvに失敗しました。相手によって接続がリセットされました - PHP Curl

2022-03-13 19:38:41

質問

このような奇妙なエラーが発生するのですが。 CURL ERROR。Recvに失敗しました。相手によって接続がリセットされました

このように、サーバーに接続していないのに、突然PHPでCURL経由でサーバーに接続しようとすると、エラーが発生します。再度CURLスクリプトを実行すると、エラーは消え、その後ずっとうまく動作します。リモートサーバを30分ほどアイドル状態にするか、リモートサーバを再起動して再度接続しようとすると、再びエラーが発生します。つまり、接続がアイドル状態になって、突然サーバーが起動して、動作して、またスリープ状態になるようです。

私のCURLスクリプトはこのような感じです。

$url = Yii::app()->params['pdfUrl'];
            $body = 'title='.urlencode($title).'&client_url='.Yii::app()->params['pdfClientURL'].'&client_id='.Yii::app()->params['pdfClientID'].'&content='.urlencode(htmlentities($content));

            $c = curl_init ($url);
            $body = array(
                "client_url"=>Yii::app()->params['pdfClientURL'],
                "client_id"=>Yii::app()->params['pdfClientID'],
                "title"=>urlencode($title),
                "content"=>urlencode($content)

            );
            foreach($body as $key=>$value) { $body_str .= $key.'='.$value.'&'; }
                rtrim($body_str,'&');

            curl_setopt ($c, CURLOPT_POST, true);
            curl_setopt ($c, CURLOPT_POSTFIELDS, $body_str);
            curl_setopt ($c, CURLOPT_RETURNTRANSFER, true);
            curl_setopt ($c, CURLOPT_CONNECTTIMEOUT , 0);
            curl_setopt ($c, CURLOPT_TIMEOUT  , 20);

            $pdf = curl_exec ($c);
            $errorCode = curl_getinfo($c, CURLINFO_HTTP_CODE);
            $curlInfo = curl_getinfo($c);
            $curlError = curl_error($c);

            curl_close ($c);

私は完全にアイデアと解決策がありません、助けてください、私はそれを感謝します!!!

を使用して何が起こるかを見るために出力を冗長化した場合。

curl_setopt ($c, CURLOPT_VERBOSE, TRUE);
curl_setopt($c, CURLOPT_STDERR, $fp); 

次のようになります。

* About to connect() to 196.41.139.168 port 80 (#0)
*   Trying 196.x.x.x... * connected
* Connected to 196.x.x.x (196.x.x.x) port 80 (#0)
> POST /serve/?r=pdf/generatePdf HTTP/1.1
Host: 196.x.x.x
Accept: */*
Content-Length: 7115
Content-Type: application/x-www-form-urlencoded
Expect: 100-continue

* Recv failure: Connection reset by peer
* Closing connection #0
012 20:23:49 GMT
< Server: Apache/2.2.15 (CentOS)
< X-Powered-By: PHP/5.3.3
< Connection: close
< Transfer-Encoding: chunked
< Content-Type: text/html; charset=UTF-8
< 
* Closing connection #0

デフォルトのヘッダーを削除するために以下を追加しましたが、まだうまくいきません。

curl_setopt ($c, CURLOPT_HTTPHEADER, array( 'Expect:' ) );

> Accept: */* Content-Length: 8414 Content-Type:
> application/x-www-form-urlencoded
> 
> * Recv failure: Connection reset by peer
> * Closing connection #0 r: Apache/2.2.15 (CentOS) < X-Powered-By: PHP/5.3.3 < Connection: close < Transfer-Encoding: chunked <
> Content-Type: text/html; charset=UTF-8 < 
> * Closing connection #0

解決方法は?

はじめに

リモートサーバーがRSTパケットを送信してきました。これは、通常のハンドシェイクではなく、接続の即時切断を意味します。

考えられる原因

A. TCP/IP

TCP/IPの問題である可能性があり、ホストと解決するか、OSをアップグレードする必要があります。 Connection reset by peer .....

B. カーネルに関するバグ

v2.6.17以降、一部のLinuxカーネルでTCPウィンドウのスケーリングに問題があることに注意してください。詳しくは、以下のバグレポートをご参照ください。

https://bugs.launchpad.net/ubuntu/+source/linux-source-2.6.17/+bug/59331

https://bugs.launchpad.net/ubuntu/+source/linux-source-2.6.20/+bug/89160

C. PHP & CURLのバグ

を使用しています。 PHP/5.3.3 これも深刻なバグがあります.私は、より新しいバージョンの PHPCURL

https://bugs.php.net/bug.php?id=52828

https://bugs.php.net/bug.php?id=52827

https://bugs.php.net/bug.php?id=52202

https://bugs.php.net/bug.php?id=50410

D. 最大伝送単位

このエラーの原因のひとつは、ネットワーク接続を通過するパケットのMTU(最大伝送単位)サイズがデフォルトの1500バイトから変更されたことです。 この場合 VPN この場合、設定中に変更する必要がある場合がほとんどです。

D. ファイアウォール:iptables

もし、この辺りのことをよく理解していないと、深刻な問題を引き起こす可能性があります。

  • そのサーバーのポート80にアクセスできること

 -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT`

  • 以下は、他のどのACCEPTの前でもなく、最後の行にあります。

  -A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited 

  • ALL DROP、REJECTを確認し、接続をブロックしていないことを確認する。

  • 一時的にすべての接続を許可し、通過するかどうかを確認する。

実験

別のサーバーまたはリモートサーバー(オンラインでは無料のクラウドホスティングがたくさんあります)で、同じスクリプトをテストしてみてください。それが動作する場合は、私の推測が正しいです... You need to update your system

その他コード関連

A. SSL

もし Yii::app()->params['pdfUrl'] はURLで https 適切なSSL設定を含んでいない場合、古いバージョンのcurlではこのエラーが発生することがあります。

解決方法 OpenSSLがインストールされ、有効になっていることを確認し、次のコードを追加してください。

curl_setopt($c, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($c, CURLOPT_SSL_VERIFYHOST, false);