php socket 实现ftp
PHP Socket 实现 FTP
使用 PHP Socket 实现 FTP 功能需要手动处理 FTP 协议的通信细节,包括建立控制连接和数据连接。以下是实现 FTP 的基本步骤和代码示例。
建立控制连接
FTP 控制连接默认使用端口 21,通过 Socket 连接到 FTP 服务器并发送命令。
$host = 'ftp.example.com';
$port = 21;
$timeout = 30;
$controlSocket = fsockopen($host, $port, $errno, $errstr, $timeout);
if (!$controlSocket) {
die("无法连接到 FTP 服务器: $errstr ($errno)");
}
// 读取欢迎消息
while ($line = fgets($controlSocket, 1024)) {
if (substr($line, 3, 1) == ' ') {
break;
}
}
登录 FTP 服务器
发送 USER 和 PASS 命令进行身份验证。

$username = 'your_username';
$password = 'your_password';
fputs($controlSocket, "USER $username\r\n");
$response = fgets($controlSocket, 1024);
if (strpos($response, '331') === false) {
die("用户名错误: $response");
}
fputs($controlSocket, "PASS $password\r\n");
$response = fgets($controlSocket, 1024);
if (strpos($response, '230') === false) {
die("密码错误: $response");
}
设置被动模式
FTP 被动模式(PASV)用于建立数据连接,服务器会返回一个 IP 和端口用于数据传输。
fputs($controlSocket, "PASV\r\n");
$response = fgets($controlSocket, 1024);
if (strpos($response, '227') === false) {
die("无法进入被动模式: $response");
}
// 解析 PASV 响应获取数据连接信息
preg_match('/\((\d+),(\d+),(\d+),(\d+),(\d+),(\d+)\)/', $response, $matches);
$dataHost = "$matches[1].$matches[2].$matches[3].$matches[4]";
$dataPort = $matches[5] * 256 + $matches[6];
建立数据连接
使用解析出的 IP 和端口建立数据连接。

$dataSocket = fsockopen($dataHost, $dataPort, $errno, $errstr, $timeout);
if (!$dataSocket) {
die("无法建立数据连接: $errstr ($errno)");
}
下载文件
发送 RETR 命令下载文件,数据通过数据连接传输。
$remoteFile = '/path/to/remote/file.txt';
$localFile = 'file.txt';
fputs($controlSocket, "RETR $remoteFile\r\n");
$response = fgets($controlSocket, 1024);
if (strpos($response, '150') === false) {
die("下载失败: $response");
}
$fileHandle = fopen($localFile, 'w');
while (!feof($dataSocket)) {
fwrite($fileHandle, fread($dataSocket, 8192));
}
fclose($fileHandle);
fclose($dataSocket);
// 检查传输完成
$response = fgets($controlSocket, 1024);
if (strpos($response, '226') === false) {
die("传输未完成: $response");
}
上传文件
发送 STOR 命令上传文件,数据通过数据连接传输。
$remoteFile = '/path/to/remote/file.txt';
$localFile = 'file.txt';
fputs($controlSocket, "STOR $remoteFile\r\n");
$response = fgets($controlSocket, 1024);
if (strpos($response, '150') === false) {
die("上传失败: $response");
}
$fileHandle = fopen($localFile, 'r');
while (!feof($fileHandle)) {
fwrite($dataSocket, fread($fileHandle, 8192));
}
fclose($fileHandle);
fclose($dataSocket);
// 检查传输完成
$response = fgets($controlSocket, 1024);
if (strpos($response, '226') === false) {
die("传输未完成: $response");
}
关闭连接
完成操作后关闭控制连接。
fputs($controlSocket, "QUIT\r\n");
fclose($controlSocket);
注意事项
- FTP 协议需要处理 ASCII 和二进制模式,使用
TYPE A或TYPE I命令切换。 - 错误处理需检查 FTP 响应码,如
4xx和5xx表示错误。 - 被动模式可能因防火墙或 NAT 导致问题,需确保网络配置正确。
通过以上步骤,可以实现基本的 FTP 文件传输功能。如需更复杂的功能(如目录操作、文件列表等),需进一步扩展命令处理逻辑。






