PHP - cURL库 - curl_error():“EPSV回复中的非法端口号”

编程语言 2026-07-12

这是我的代码(当然是伪数据):

<?php

error_reporting(E_ALL);
ini_set('display_errors', '1');

$curl = curl_init();
$file = fopen("x.x", 'w');
curl_setopt($curl, CURLOPT_URL, "ftp://example.com/nice.file");
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_FILE, $file);
curl_setopt($curl, CURLOPT_USERPWD, "user:secret");
curl_setopt($curl, CURLOPT_FTP_USE_EPSV, true);
$res = curl_exec($curl);
$info = curl_getinfo($curl);
$error = curl_error($curl);
$errno = curl_errno($curl);
curl_close($curl);
fclose($file);

echo "\n=== res ===\n" ;
var_dump($res);

echo "\n=== error ===\n" ;
var_dump($error);

echo "\n=== errno ===\n" ;
var_dump($errno);

echo "\n=== info ===\n" ;
print_r($info);

?>

nice.file 未下载,$error 字符串被设置为

EPSV回复中的端口号无效

我不明白这条信息的含义。使用 lftp 客户端在Linux上,数据传输可以正常进行。

解决方案

已关闭EPSV

curl_setopt($curl, CURLOPT_FTP_USE_EPSV, false);

或在CLI中:

--disable-epsv

如果再次出现(NAT背后的经典问题)

添加这个

curl_setopt($curl, CURLOPT_FTP_SKIP_PASV_IP, true);

这点非常关键,因为某些服务器在PASV中会发送私有IP:

227 Entering Passive Mode (10,0,0,5,195,44)

curl尝试连接 → 无法访问 → 失败。

这个选项:

不要使用服务器给出的IP,而要使用控制连接的IP
这句话。


根源在于

防火墙FTP ALG已开启:

nf_conntrack_ftp

并且EPSV可能被错误地改写。

在Linux上

sudo modprobe -r nf_conntrack_ftp
sudo modprobe -r nf_nat_ftp

curl_setopt($curl, CURLOPT_FTP_USE_EPSV, false);
curl_setopt($curl, CURLOPT_FTP_SKIP_PASV_IP, true);

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章