"php_connect_nonb()失败:操作正在进行中(115)"间歇性发生。

19

我们使用PHP cron job通过FTP将一些文件发送给第三方。

但是有时我们会遇到以下错误:

ErrorException [ 2 ]: ftp_put(): php_connect_nonb() failed: Operation 
now in progress (115) ~ MODPATH/fileop/classes/Drivers/Fileop/Ftp.php [ 37 ]

当我说“有时候”时,我的意思确切就是那个样子;大多数时候都没有问题,但有五分之一的时间会出现错误。这不是因为文件本身的问题,因为如果我们再试一次,它们就可以成功传输。

我们在网上找到了类似的问题-与PHP中的NAT设备或防火墙配置有关的漏洞,但是暗示是如果是这种情况,它就永远无法正常工作。

那么,为什么有时可以工作而有时不能?


是的,我看过那个。但是那个用户似乎完全无法连接。不确定服务器是哪个版本;我需要从第三方那里找出来。 - Mikey C
哎呀,我不能使用SCP,因为第三方没有提供这个选项。 - Mikey C
你有查看过这个链接吗?http://www.elitehosts.com/blog/php-ftp-passive-ftp-server-behind-nat-nightmare/ - olaurendeau
是的,谢谢,我在我的问题中链接了那个。如果那是问题的话,那肯定永远不会起作用吧?我不想在没有把握能修好它的情况下修补一个活着的服务器,而且我很难复现它。 - Mikey C
3
我也遇到了同样的问题。我可以使用标准的OSX FTP客户端(Transmit)连接FTP服务器,但在我的代码中却无法连接,它会挂起,并返回有关正在进行中的错误。然而,如果Web服务器与FTP服务器在同一个局域网中,则不会出现此问题。一旦Web服务器在FTP局域网外部,就会发生此错误。不确定如何修复:( - ariestav
显示剩余2条评论
6个回答

25
ftp_set_option($ftpconn, FTP_USEPASVADDRESS, false);

在设置连接的被动模式之前,使用以下代码:ftp_pasv($ftpconn, true);

解决了我的问题


1
我的代码:$conn = ftp_connect($server); $login = ftp_login($conn, $username, $password); ftp_set_option($conn, FTP_USEPASVADDRESS, false); ftp_pasv($conn, true); ftp_put($conn, $remote_file, $file, FTP_ASCII); - Cristian A. Rodríguez Enríquez

11

FTP(S)使用随机端口建立数据连接;间歇性的成功率表明客户端和/或服务器机器上的防火墙未允许所有端口。FTP服务器可以设置传入(PASV)数据连接的端口范围。

此页面有一个很好的总结:

“简单的方法是允许FTP服务器和客户端通过防火墙进行无限制访问,但如果您想限制它们的访问权限只能使用‘已知’端口,则必须了解4种不同的情况。” “1)FTP服务器应允许接受TCP连接到端口21,并从端口20建立TCP连接到任何(远程临时)端口。” “2)FTP服务器应允许接受TCP连接到端口21,同时也应允许接受TCP连接到任何临时端口!” “3)FTP客户端应允许创建TCP连接到端口21,并允许接受从端口20到任何临时端口的TCP连接。” “4)FTP客户端应允许创建TCP连接到端口21,并允许创建TCP连接到任何其他(远程临时)端口!”

2
所以,在对我的FTP服务器进行了一些调查并阅读了您提供的elitehosts.com链接后,我写下了这篇答案。
我正在使用FileZilla FTP服务器,需要输入特定设置才能使其正常工作。进入服务器设置,有一个名为“被动模式设置”的区域。在该对话框中,有一个名为“IPv4特定”的区域,在其中有一个标记为“用于被动模式传输的外部服务器IP地址:”的设置。它是一个单选按钮集合,并且默认设置为“默认”,但由于FTP服务器经过NAT,我将该单选按钮从“默认”更改为“使用以下IP:”,并输入由ISP提供的网关的外部IP地址。
设置完成后,它就可以正常工作了!不确定您的FTP服务器是否经过NAT,但我认为我会在此线程中提供答案,因为它似乎相关。

1
除了Cees的回答之外,我在EC2上运行vsftp并不得不注释掉listen_ipv6 = YES,listen = YES,然后“service vsftpd restart”。
虽然文档说它也会监听ipv4,但实际上它没有,这解决了问题。

1
对我来说,我所要做的就是删除ftp_pasv( $ftpconn, true );,然后一切都可以完美地运行。我还不确定原因,但我正在努力找出来,当我找到原因时,我一定会回来的。

那么?你找到原因了吗?今天下午我也遇到了同样的问题,按照你说的做了,就解决了。 - Rogerio Brito Soares
我进行了一些调查,看起来你不能信任我提出的解决方案...一旦我找到最可靠的解决方案,我会分享。 - Lotes Molapo

0

这应该是在jj_dev2的评论下面,但由于声望不够,我无法添加评论。但也许对某些人有帮助,所以我在这里发布。

我们遇到了与原帖描述相同的问题。在我们的情况下,它适用于许多客户 - 除了一个。

jj_dev2评论中的解决方案对我们有效。因此,我们调查了ftp_set_option($conn, FTP_USEPASVADDRESS, false)实际上是做什么的。基于此,我们发现实际上客户的FTPS服务器配置不正确。

响应PASV命令(ftp_pasv($conn, true))时,FTP服务器返回一个IP地址,PHP FTP客户端将使用该地址进行数据传输。在我们的情况下,FTP服务器返回的是内部IP地址,而不是我们连接到的公共IP地址。客户必须修复其FTP服务器设置,以便FTP服务器在PASV命令响应中发送外部IP地址。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接