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

时间:2012-04-23 17:55:42

标签: php curl yii

我遇到了这个奇怪的错误, 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

7 个答案:

答案 0 :(得分:93)

简介

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

可能的原因

一个。 TCP / IP

您可能需要解决主机上的TCP / IP问题,或者在远程服务器完成下载内容之前连接升级您的操作系统,然后才能将内容下载到Connection reset by peer .....

B中。 Kannel Bug

请注意,在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

℃。 PHP&amp; CURL Bug

您使用的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 
  • 检查所有DROP,REJECT并确保它们没有阻止您的连接

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

实验

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

其他代码相关

一个。 SSL

如果Yii::app()->params['pdfUrl']https未包含正确SSL设置的网址,则旧版卷曲中也会导致此错误

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

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

我希望它有所帮助

答案 1 :(得分:10)

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

通常情况下,网络错误会在一段时间后自行解决,但听起来你已经花了一些时间。

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

虽然我不能确定但是,我相信cURL在历史上一直都是SSL证书,而Open SSL却没有。

无论如何,尝试在服务器上安装Open SSL并再试一次,这样可以帮助您摆脱这个错误。

答案 2 :(得分:3)

那么Yii::app()->params['pdfUrl']提供的网址是什么?你说它应该是https,但是日志显示它在端口80上连接...几乎没有设置服务器来接受https连接。 cURL非常聪明,知道https应该在443端口上......这表明你的网址有些不可思议的内容,如:https://196.41.139.168:80/serve/?r=pdf/generatePdf

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

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

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

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

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

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

$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);

答案 3 :(得分:1)

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

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

由于 Ganesh PNS

答案 4 :(得分:0)

在我的情况下,URL中存在问题。我已经使用了https://example.com - 但他们确保使用{&3;}。 - 所以当我切换到https://www.example.com时一切正常。正确的标题已发送给主持人:www.example.com&#39;。

你可以尝试在firefox brwoser中提出请求,坚持并复制为cURL - 我是如何找到它的。

答案 5 :(得分:0)

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

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

curl --sslv3 https://example.com

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

  

卷曲:(35)通过对等方重置TCP连接

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

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

答案 6 :(得分:0)

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

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

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

  • 将URL重建为:http:LB URL /
  • 尝试LB URL ...
  • 设置了TCP_NODELAY
  • 已连接到LB URL(LB URL)端口80(#0)
      

    GET / HTTP / 1.1   主机:localhost   用户代理:curl / 7.60.0   接受: /   连接:升级   升级:websocket   来源:http://LB网址:80

  • 接收失败:对等连接重置
  • 关闭连接0 curl:(56)接收失败:对等重置连接
相关问题