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

zsohkypk  于 2022-11-09  发布在  PHP
关注(0)|答案(7)|浏览(837)

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

我完全出的想法和解决方案,请帮助,我会很感激!!!
如果我使用以下命令详细显示输出

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
ctzwtxfj

ctzwtxfj1#

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

可能的原因

A.TCP/IP协议
这可能是一个TCP/IP问题,您需要解决与您的主机或升级您的操作系统大多数时间的连接是关闭与远程服务器之前,它完成下载的内容导致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
  • 检查是否存在所有DROP、REJECT,并确保它们没有阻止您的连接
  • 暂时允许所有连接,查看是否有敌人通过

实验

尝试在不同的服务器或远程服务器上(这么多免费云托管在线),并测试相同的脚本.如果它的工作,那么我的猜测是正确的... You need to update your system

其他代码相关

答:SSL
如果Yii::app()->params['pdfUrl']https的url,而不包括正确的SSL设置,则在旧版本的curl中也会导致此错误
解决方案:确保已安装并启用OpenSSL,然后将其添加到代码中

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

64jmpszr2#

通常这个错误意味着与服务器建立了连接,但是连接被远程服务器关闭了。这可能是由于服务器速度慢,远程服务器有问题,网络问题,或者(可能)发送到远程服务器的数据出现了某种安全错误,但我发现这种情况不太可能。
通常情况下,网络错误会在一段时间内自行解决,但听起来您已经给了它一段时间。
cURL有时有SSL和SSL证书的问题。我认为你的Apache和/或PHP是用最新版本的cURL和cURL SSL库编译的,而且我认为你的Web服务器上没有安装OpenSSL。
虽然我不能肯定,但是,我相信cURL在历史上一直是flakey与SSL证书,而开放SSL没有。
无论如何,尝试在服务器上安装开放SSL,然后重试,这应该可以帮助您摆脱这个错误。

8ftvxx2r

8ftvxx2r3#

我面临着同样的错误,但方式不同。
当您使用特定的SSL协议 curl 页面时。

curl --sslv3 https://example.com

如果目标服务器不支持--sslv 3,则错误将为
curl:(35)TCP连接被对等方重置
使用支持的协议,错误将消失。

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

k3fezbri4#

那么Yii::app()->params['pdfUrl']给出的URL是什么呢?您说应该是https,但是日志显示它连接到端口80...几乎没有服务器设置为接受https连接。cURL足够聪明,知道https应该在端口443...这表明您的URL中有一些不可靠的东西,如: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);
8yparm6h

8yparm6h5#

这是一个防火墙问题,如果您使用的是VMware应用程序,请确保防病毒软件上的防火墙已关闭或允许连接。
如果此服务器位于安全网络上,请查看服务器的防火墙规则。
感谢Ganesh PNS

7fyelxc5

7fyelxc56#

我们也遇到了同样的问题,在建立一个WebSocket连接到负载均衡器。问题是在LB,接受端口80上的http连接并将请求转发到节点(端口8080上的tomcat应用程序)。我们已将其更改为接受tcp(http已更改为“tcp”)连接到端口80。因此,第一个握手请求被转发到节点,并在某个随机(据我所知,可能是错误的)端口上成功建立了一个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_节点延迟设置
  • 已连接到LB URL(LB URL)端口80(#0)

GET / HTTP/1.1主机:本地主机用户代理: curl /7.60.0接受:/ 连接:升级升级:WebSocket来源:网址:80

  • 接收失败:对等方重置连接
  • 关闭连接0 curl:(56)接收失败:对等方重置连接
b4wnujal

b4wnujal7#

在我的情况下有问题的网址。我已经使用https://example.com-但他们确保'www.' -所以当我切换到https://www.example.com一切都是好的。正确的头被发送'主机:www.example.com“的网站。
你可以尝试在firefox brwoser中发出请求,将其持久化并复制为cURL --这就是我找到它的方法。

相关问题