curl错误:接收失败:由对等重置的连接 – PHP Curl

我有这个奇怪的错误, curl错误:接收失败:连接重置由对等

这是如何发生的,如果我没有连接到服务器,并突然尝试通过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); 

我完全没有想法和解决scheme,请帮助,我会感激!

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

 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.xxx.. * connected * Connected to 196.xxx (196.xxx) port 80 (#0) > POST /serve/?r=pdf/generatePdf HTTP/1.1 Host: 196.xxx 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问题,你需要解决您的主机或升级您的操作系统大多数时间之前连接closures远程服务器之前,它完成下载内容导致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

C. PHP&CURL错误

您正在使用PHP/5.3.3 ,它也有一些严重的错误…我会build议你使用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. 最大传输单位

导致此错误的一个常见原因是,通过networking连接传输的数据包的MTU(最大传输单元)大小已从默认的1500字节更改。 如果您configuration了VPN则最有可能在configuration期间必须更改

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 
  • 检查所有的丢弃,拒绝,并确保他们没有阻止你的连接

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

实验

尝试一个不同的服务器或远程服务器(这么多收费云托pipe在线)和testing相同的脚本..如果它的工作,那么我猜测是一样好… You need to update your system

其他代码相关

A. SSL

如果Yii::app()->params['pdfUrl']是一个包含https的url,但是不包含正确的SSL设置,也会导致旧版本的curl

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

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

我希望它有帮助

通常这个错误意味着与服务器build立连接,但是连接被远程服务器closures。 这可能是由于服务器速度慢,远程服务器问题,networking问题,或者(可能)某种安全错误,数据被发送到远程服务器,但我觉得不太可能。

通常networking错误会在一段时间后自行解决,但听起来好像你已经给了它一些时间了。

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

虽然我不能确定但是,我相信历史上cURL在SSL证书方面一直很失败,而Open SSL则没有。

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

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

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

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

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

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

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

所有这一切都汇集到最终的代码中:

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

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

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

感谢Ganesh PNS

在我的情况下,在URL中有问题。 我使用https://example.com – 但他们确保'www。' – 所以当我切换到https://www.example.com一切都很好。; 正确的标题发送“主机:www.example.com”。

你可以尝试使用firefox brwoser发送请求,将其保存并复制为cURL – 我如何find它。