CURL 错误:接收失败:对等方重置连接 - PHP Curl

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10285700/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 21:49:17  来源:igfitidea点击:

CURL ERROR: Recv failure: Connection reset by peer - PHP Curl

phpcurlyii

提问by Elitmiar

I'm having this strange error, CURL ERROR: Recv failure: Connection reset by peer

我遇到了这个奇怪的错误,CURL ERROR: Recv failure: Connection reset by peer

This is how it happens, if I did not connect to the server and all of a sudden trying to connect to the server via CURL in PHP I get the error. When I run the CURL script again the error disappears and then works well the whole time, if I leave the remote server idle for about 30mins or reboot the remote server and try to connect again, I get the error again. So it seems like the connection is idle and then all of sudden the server wakes up and then works and then sleeps again.

这就是它发生的方式,如果我没有连接到服务器并且突然尝试通过 PHP 中的 CURL 连接到服务器,我会收到错误消息。当我再次运行 CURL 脚本时,错误消失,然后一直运行良好,如果我让远程服务器空闲大约 30 分钟或重新启动远程服务器并再次尝试连接,我会再次收到错误消息。所以看起来连接是空闲的,然后服务器突然醒来,然后工作,然后再次休眠。

This is how my CURL script looks.

这就是我的 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);

I'm totally out of ideas and solutions, please help, I'll appreciate it!!!

我完全没有想法和解决方案,请帮助,我将不胜感激!!!

If I verbose the output to see what happens using

如果我详细输出以查看使用

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

I get the following

我得到以下

* 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

I've added in the following toe remove the default header and still no luck:

我在以下脚趾中添加了删除默认标题,但仍然没有运气:

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

回答by Baba

Introduction

介绍

The remote server has sent you a RST packet, which indicates an immediate dropping of the connection, rather than the usual handshake.

远程服务器向您发送了一个 RST 数据包,这表明连接立即断开,而不是通常的握手。

Possible Causes

可能的原因

A. TCP/IP

A. TCP/IP

It might be TCP/IP issue you need to resolve with your host or upgrade your OS most times connection is close before remote server before it finished downloading the content resulting to Connection reset by peer.....

这可能是 TCP/IP 问题,您需要与主机一起解决或升级您的操作系统,大多数情况下,在远程服务器完成下载内容之前,连接已关闭,导致Connection reset by peer.....

B. Kannel Bug

B. Kannel Bug

Note that there are some issues with TCP window scaling on some Linux kernels after v2.6.17. See the following bug reports for more information:

请注意,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.17/+bug/59331

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

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

C. PHP & CURL Bug

C. PHP & CURL 错误

You are using PHP/5.3.3which has some serious bugs too ... i would advice you work with a more recent version of PHPand CURL

您正在使用PHP/5.3.3它也有一些严重的错误......我建议您使用更新版本的PHPCURL

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

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

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

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

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

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

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

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

D. Maximum Transmission Unit

D.最大传输单元

One common cause of this error is that the MTU (Maximum Transmission Unit) size of packets travelling over your network connection have been changed from the default of 1500 bytes. If you have configured VPNthis most likely must changed during configuration

此错误的一个常见原因是通过网络连接传输的数据包的 MTU(最大传输单元)大小已从默认值 1500 字节更改。如果您已配置,VPN这很可能必须在配置期间更改

D. Firewall : iptables

D.防火墙:iptables

If you don't know your way around this guys they would cause some serious issues .. try and access the server you are connecting to check the following

如果您不了解这些人的方式,他们会导致一些严重的问题.. 尝试访问您正在连接的服务器以检查以下内容

  • You have access to port 80 on that server
  • 您可以访问该服务器上的端口 80

Example

例子

 -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT`
  • The Following is at the last line not before any other ACCEPT
  • 以下是在任何其他 ACCEPT 之前的最后一行

Example

例子

  -A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited 
  • Check for ALL DROP , REJECT and make sure they are not blocking your connection

  • Temporary allow all connection as see if it foes through

  • 检查 ALL DROP , REJECT 并确保它们没有阻止您的连接

  • 临时允许所有连接,看看它是否通过

Experiment

实验

Try a different server or remote server ( So many fee cloud hosting online) and test the same script .. if it works then i guesses are as good as true ... You need to update your system

尝试不同的服务器或远程服务器(网上有这么多收费的云托管)并测试相同的脚本..如果它有效,那么我猜和真的一样好...... You need to update your system

Others Code Related

其他代码相关

A. SSL

A. SSL

If Yii::app()->params['pdfUrl']is a url with httpsnot including proper SSL setting can also cause this error in old version of curl

如果Yii::app()->params['pdfUrl']https不包含正确 SSL 设置的 url也会在旧版本的 curl 中导致此错误

Resolution : Make sure OpenSSL is installed and enabled then add this to your code

解决方案:确保已安装并启用 OpenSSL,然后将其添加到您的代码中

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

I hope it helps

我希望它有帮助

回答by Aamer

Normally this error means that a connection was established with a server but that connection was closed by the remote server. This could be due to a slow server, a problem with the remote server, a network problem, or (maybe) some kind of security error with data being sent to the remote server but I find that unlikely.

通常,此错误意味着已与服务器建立连接,但该连接已被远程服务器关闭。这可能是由于服务器速度慢、远程服务器有问题、网络问题,或者(可能)数据发送到远程服务器时出现某种安全错误,但我认为这不太可能。

Normally a network error will resolve itself given a bit of time, but it sounds like you've already given it a bit of time.

通常,网络错误会在一段时间后自行解决,但听起来您已经给了它一点时间。

cURL sometimes having issue with SSL and SSL certificates. I think that your Apache and/or PHP was compiled with a recent version of the cURL and cURL SSL libraries plus I don't think that OpenSSL was installed in your web server.

cURL 有时会出现 SSL 和 SSL 证书问题。我认为您的 Apache 和/或 PHP 是使用最新版本的 cURL 和 cURL SSL 库编译的,而且我认为您的 Web 服务器中没有安装 OpenSSL。

Although I can not be certain However, I believe cURL has historically been flakey with SSL certificates, whereas, Open SSL does not.

虽然我不能确定但是,我相信 cURL 在历史上一直使用 SSL 证书,而 Open SSL 则不然。

Anyways, try installing Open SSL on the server and try again and that should help you get rid of this error.

无论如何,尝试在服务器上安装 Open SSL 并重试,这应该可以帮助您摆脱此错误。

回答by Rudu

So what is the URL that Yii::app()->params['pdfUrl']gives? You say it should be https, but the log shows it's connecting on port 80... which almost no server is setup to accept https connections on. cURL is smart enough to know https should be on port 443... which would suggest that your URL has something wonky in it like: https://196.41.139.168:80/serve/?r=pdf/generatePdf

那么Yii::app()->params['pdfUrl']给出的网址是什么?你说它应该是 https,但日志显示它正在连接端口 80...几乎没有服务器设置为接受 https 连接。cURL 足够聪明,知道 https 应该在端口 443 上......这表明你的 URL 有一些不稳定的东西,比如:https://196.41.139.168:80/serve/?r=pdf/generatePdf

That's going to cause the connection to be terminated, when the Apache at the other end cannot do https communication with you on that port.

当另一端的 Apache 无法在该端口上与您进行 https 通信时,这将导致连接终止。

You realize your first $bodydefinition gets replaced when you set $bodyto an array two lines later? {Probably just an artifact of you trying to solve the problem} You're also not encoding the client_urland client_idvalues (the former quite possibly containing characters that need escaping!) Oh and you're appending to $body_strwithout first initializing it.

$body当您$body在两行之后设置数组时,您意识到您的第一个定义被替换了吗?{可能只是你试图解决问题的产物}你也没有对client_urlclient_id值进行编码(前者很可能包含需要转义的字符!)哦,你在$body_str没有先初始化的情况下追加到它。

From your verbose output we can see cURL is adding a content-lengthheader, but... is it correct? I can see some comments out on the internets of that number being wrong (especially with older versions)... if that number was to small (for example) you'd get a connection-reset before all the data is sent. You can manually insert the header:

从您的详细输出中,我们可以看到 cURL 正在添加content-length标题,但是...是否正确?我可以在互联网上看到一些关于该数字错误的评论(尤其是旧版本)...如果该数字很小(例如),您将在发送所有数据之前进行连接重置。您可以手动插入标题:

curl_setopt ($c, CURLOPT_HTTPHEADER, 
   array("Content-Length: ". strlen($body_str))); 

Oh and there's a handy function http_build_querythat'll convert an array of name/value pairs into a URL encoded string for you.

哦,还有一个方便的函数http_build_query可以为您将名称/值对数组转换为 URL 编码的字符串。

All this rolls up into the final code:

所有这些都汇总到最终代码中:

$post=http_build_query(array(
  "client_url"=>Yii::app()->params['pdfClientURL'],
  "client_id"=>Yii::app()->params['pdfClientID'],
  "title"=>$title,
  "content"=>$content));

//Open to URL
$c=curl_init(Yii::app()->params['pdfUrl']);
//Send post
curl_setopt ($c, CURLOPT_POST, true);
//Optional: [try with/without]
curl_setopt ($c, CURLOPT_HTTPHEADER, array("Content-Length: ".strlen($post))); 
curl_setopt ($c, CURLOPT_POSTFIELDS, $post);
curl_setopt ($c, CURLOPT_RETURNTRANSFER, true);
curl_setopt ($c, CURLOPT_CONNECTTIMEOUT , 0);
curl_setopt ($c, CURLOPT_TIMEOUT  , 20);
//Collect result
$pdf = curl_exec ($c);
$curlInfo = curl_getinfo($c);
curl_close($c);

回答by xs2rashid

I faced same error but in a different way.

我遇到了同样的错误,但方式不同。

When you curl a page with a specific SSL protocol.

当您使用特定 SSL 协议卷曲页面时。

curl --sslv3 https://example.com

If --sslv3 is not supported by the target server then the error will be

如果目标服务器不支持 --sslv3 则错误将是

curl: (35) TCP connection reset by peer

curl: (35) 对等方重置 TCP 连接

With the supported protocol, error will be gone.

使用支持的协议,错误将消失。

curl --tlsv1.2 https://example.com

回答by GANESH

This is a firewall issue, if you are using a VMware application, make sure the firewall on the antivirus is turned off or allowing connections.

这是一个防火墙问题,如果您使用的是 VMware 应用程序,请确保防病毒软件上的防火墙已关闭或允许连接。

If this server is on a secure network, please have a look at firewall rules of the server.

如果此服务器在安全网络上,请查看服务器的防火墙规则。

Thanks Ganesh PNS

感谢 Ganesh PNS

回答by Radek

In my case there was problem in URL. I've use https://example.com- but they ensure 'www.' - so when i switched to https://www.example.comeverything was ok. The proper header was sent 'Host: www.example.com'.

就我而言,URL 存在问题。我使用过https://example.com- 但他们确保“www”。- 所以当我切换到https://www.example.com 时一切正常。正确的标头已发送“主机:www.example.com”。

You can try make a request in firefox brwoser, persist it and copy as cURL - that how I've found it.

您可以尝试在 firefox brwoser 中发出请求,将其保留并复制为 cURL - 我是如何找到它的。

回答by kumar ram

We had the same issue, in making a websocket connection to the Load Balancer. The issue is in LB, accepting http connection on port 80 and forwarding the request to node (tomcat app on port 8080). We have changed this to accept tcp (http has been changed as 'tcp') connection on port 80. So the first handshake request is forwarded to Node and a websocket connection is made successfully on some random( as far as i know, may be wrong) port.

我们在与负载均衡器建立 websocket 连接时遇到了同样的问题。问题出在 LB 中,在端口 80 上接受 http 连接并将请求转发到节点(端口 8080 上的 tomcat 应用程序)。我们已将其更改为在端口 80 上接受 tcp(http 已更改为 'tcp')连接。因此,第一个握手请求被转发到 Node,并且在某个随机情况下成功建立了一个 websocket 连接(据我所知,可能是错误)端口。

below command has been used to test the websocket handshake process.

下面的命令已用于测试 websocket 握手过程。

curl -v -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" -H "Host: localhost" -H "Origin: http://LB URL:80" http://LB URL

curl -v -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" -H "Host: localhost" -H "Origin: http://LB URL:80" http://LB URL

  • Rebuilt URL to: http:LB URL/
  • Trying LB URL...
  • TCP_NODELAY set
  • Connected to LB URL (LB URL) port 80 (#0)

    GET / HTTP/1.1 Host: localhost User-Agent: curl/7.60.0 Accept: /Connection: Upgrade Upgrade: websocket Origin: http://LBURL:80

  • Recv failure: Connection reset by peer
  • Closing connection 0 curl: (56) Recv failure: Connection reset by peer
  • 重建 URL 为:http:LB URL/
  • 正在尝试 LB 网址...
  • TCP_NODELAY 设置
  • 连接到 LB URL (LB URL) 端口 80 (#0)

    GET / HTTP/1.1 Host: localhost User-Agent: curl/7.60.0 Accept: /Connection: Upgrade Upgrade: websocket Origin: http://LBURL:80

  • 接收失败:对等方重置连接
  • 关闭连接 0 curl: (56) Recv failure: Connection reset by peer