自动发帖软件
标题:
AIWROK软件安卓脚本FTP上传下载例子
[打印本页]
作者:
发帖软件
时间:
2 小时前
标题:
AIWROK软件安卓脚本FTP上传下载例子
AIWROK软件安卓脚本FTP上传下载例子
3.png
(989.33 KB, 下载次数: 0)
2 小时前
上传
/**
* AIWROK 简易FTP工具 - 纯Java Socket实现
* 交流QQ群: 711841924 (群一) / 528816639 (苹果脚本内测群)s
*/
// ==================== FTP配置 ====================
// 配置FTP服务器连接信息
var FTPConfig = {
host: "38.67.75.157", // FTP服务器地址
port: 21, // FTP端口(默认21)
username: "fghgdfhfdh", // 登录用户名
password: "aH6CEtK6X77J", // 登录密码
timeout: 60000, // 连接超时时间(毫秒)
encoding: "UTF-8" // 字符编码
};
// ==================== FTP客户端 ====================
// 使用IIFE(立即执行函数)创建FTPClient对象
// 封装所有FTP操作,保持全局命名空间清洁
var FTPClient = (function() {
// 私有变量 - FTP连接状态
var controlSocket = null; // 控制通道Socket(发送命令)
var dataSocket = null; // 数据通道Socket(传输文件)
var reader = null; // 控制通道读取器
var writer = null; // 控制通道写入器
var isConnected = false; // 连接状态标志
/**
* 读取FTP服务器响应
* 从控制通道读取一行文本
* @returns {string|null} 服务器响应的文本,失败返回null
*/
function readResponse() {
try {
var line = reader.readLine();
if (line) console.log("FTP: " + line);
return line;
} catch (e) {
return null;
}
}
/**
* 发送FTP命令并等待响应
* @param {string} cmd - FTP命令(如 USER, PASS, PASV等)
* @returns {string|null} 服务器响应,失败返回null
*/
function sendCommand(cmd) {
try {
writer.write(cmd + "\r\n"); // FTP命令以\r\n结尾
writer.flush(); // 立即发送
sleep.second(0.5); // 等待服务器响应
return readResponse(); // 读取响应
} catch (e) {
return null;
}
}
/**
* 连接FTP服务器并登录
* 建立控制通道,完成用户认证
* @param {Object} config - FTP配置对象(host, port, username, password等)
* @returns {boolean} 连接成功返回true,失败返回false
*/
function connect(config) {
try {
console.log("连接FTP: " + config.host);
// 1. 创建控制通道Socket连接
controlSocket = new java.net.Socket(config.host, config.port);
controlSocket.setSoTimeout(config.timeout); // 设置超时
// 2. 创建输入输出流(使用指定编码)
var InputStreamReader = java.io.InputStreamReader;
var OutputStreamWriter = java.io.OutputStreamWriter;
var BufferedReader = java.io.BufferedReader;
var BufferedWriter = java.io.BufferedWriter;
reader = new BufferedReader(new InputStreamReader(controlSocket.getInputStream(), config.encoding));
writer = new BufferedWriter(new OutputStreamWriter(controlSocket.getOutputStream(), config.encoding));
// 3. 读取服务器欢迎消息(220开头)
var welcome = readResponse();
if (!welcome || !welcome.startsWith("220")) {
disconnect();
return false;
}
// 4. 读取所有多行欢迎消息(Pure-FTPd会发送多条220-开头的消息)
sleep.second(0.3);
var line;
while ((line = reader.readLine()) !== null) {
if (!line.startsWith("220-")) break; // 遇到非220-的行就停止
}
// 5. 发送用户名(USER命令)
var resp = sendCommand("USER " + config.username);
if (!resp || !resp.startsWith("331")) { // 331表示需要密码
disconnect();
return false;
}
// 6. 发送密码(PASS命令)
resp = sendCommand("PASS " + config.password);
if (!resp || !resp.startsWith("230")) { // 230表示登录成功
disconnect();
return false;
}
console.log("✓ 登录成功");
isConnected = true;
return true;
} catch (e) {
console.log("连接失败: " + e.message);
disconnect();
return false;
}
}
/**
* 设置被动模式(PASV)
* FTP被动模式:服务器开启数据端口,客户端连接
* 自动处理内网IP映射(将10.x.x.x替换为公网IP)
* @returns {boolean} 设置成功返回true,失败返回false
*/
function setupPassiveMode() {
try {
// 关闭旧的数据通道
if (dataSocket) {
try { dataSocket.close(); } catch(e) {}
dataSocket = null;
}
// 发送PASV命令,获取服务器数据端口
var resp = sendCommand("PASV");
if (!resp || !resp.startsWith("227")) return false; // 227表示进入被动模式
// 解析PASV响应: 227 Entering Passive Mode (h1,h2,h3,h4,p1,p2)
var match = resp.match(/\(([^)]+)\)/);
if (!match) return false;
var parts = match[1].split(",");
var port = parseInt(parts[4]) * 256 + parseInt(parts[5]); // 计算端口号
var ip = parts[0] + "." + parts[1] + "." + parts[2] + "." + parts[3];
// 重要:如果服务器返回内网IP,替换为配置的公网IP
// 这是因为FTP服务器在NAT后面,会返回内网地址
if (ip.startsWith("10.") || ip.startsWith("192.168.")) {
console.log("检测到内网IP: " + ip + ",使用服务器地址: " + FTPConfig.host);
ip = FTPConfig.host;
}
// 创建数据通道Socket连接
dataSocket = new java.net.Socket(ip, port);
dataSocket.setSoTimeout(60000); // 数据传输超时60秒
return true;
} catch (e) {
console.log("被动模式设置失败: " + e.message);
return false;
}
}
/**
* 上传文件到FTP服务器
* 使用被动模式传输,支持二进制文件
* @param {string} localPath - 本地文件路径(如 /sdcard/test.txt)
* @param {string} remotePath - 远程文件路径(如 /test.txt)
* @returns {boolean} 上传成功返回true,失败返回false
*/
function upload(localPath, remotePath) {
if (!isConnected) return false;
console.log("上传: " + localPath + " -> " + remotePath);
// 检查本地文件是否存在
var file = new java.io.File(localPath);
if (!file.exists()) {
console.log("文件不存在: " + localPath);
return false;
}
// 设置被动模式,建立数据通道
if (!setupPassiveMode()) return false;
// 发送STOR命令,准备接收文件
var resp = sendCommand("STOR " + remotePath);
if (!resp || !resp.startsWith("150")) return false; // 150表示准备接收
// 读取本地文件并发送到数据通道
var fis = new java.io.BufferedInputStream(new java.io.FileInputStream(file));
var out = dataSocket.getOutputStream();
var buffer = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 4096); // 4KB缓冲区
var len;
while ((len = fis.read(buffer)) !== -1) {
out.write(buffer, 0, len); // 写入数据通道
}
// 关闭流和Socket
fis.close();
out.close();
dataSocket.close();
dataSocket = null;
// 读取最终响应(226表示传输完成)
sleep.second(0.5);
var finalResp;
while ((finalResp = readResponse()) !== null) {
if (finalResp.startsWith("226 ")) { // 226表示文件传输成功
console.log("✓ 上传成功");
return true;
}
}
return false;
}
/**
* 从FTP服务器下载文件
* 使用被动模式传输,支持二进制文件
* @param {string} remotePath - 远程文件路径(如 /test.txt)
* @param {string} localPath - 本地保存路径(如 /sdcard/test.txt)
* @returns {boolean} 下载成功返回true,失败返回false
*/
function download(remotePath, localPath) {
if (!isConnected) return false;
console.log("下载: " + remotePath + " -> " + localPath);
// 设置被动模式,建立数据通道
if (!setupPassiveMode()) return false;
// 发送RETR命令,请求下载文件
var resp = sendCommand("RETR " + remotePath);
if (!resp || !resp.startsWith("150")) return false; // 150表示准备发送
// 从数据通道接收数据并保存到本地文件
var fos = new java.io.BufferedOutputStream(new java.io.FileOutputStream(new java.io.File(localPath)));
var input = dataSocket.getInputStream();
var buffer = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 4096); // 4KB缓冲区
var len;
var total = 0;
console.log("开始接收...");
try {
var startTime = new Date().getTime();
var timeout = 30000; // 30秒超时保护
while ((len = input.read(buffer)) !== -1) {
fos.write(buffer, 0, len); // 写入本地文件
total += len;
// 检查是否超时
var elapsed = new Date().getTime() - startTime;
if (elapsed > timeout) {
console.log("超时: 已接收 " + total + " 字节");
break;
}
}
console.log("接收完成: " + total + " 字节");
} catch (e) {
console.log("接收出错: " + e.message);
}
// 关闭流和Socket
fos.close();
input.close();
dataSocket.close();
dataSocket = null;
// 读取最终响应(226表示传输完成)
sleep.second(0.5);
var finalResp;
while ((finalResp = readResponse()) !== null) {
if (finalResp.startsWith("226 ")) { // 226表示文件传输成功
console.log("✓ 下载成功");
return true;
}
}
return false;
}
/**
* 获取FTP目录列表
* 使用LIST命令获取指定目录的文件列表
* @param {string} remotePath - 远程目录路径(如 /)
* @returns {Array} 文件列表数组,每个元素是一行LIST输出
*/
function listDir(remotePath) {
if (!isConnected) return [];
console.log("列出目录: " + remotePath);
// 设置被动模式
if (!setupPassiveMode()) return [];
// 发送LIST命令
var resp = sendCommand("LIST " + remotePath);
if (!resp || !resp.startsWith("150")) return []; // 150表示准备发送数据
// 从数据通道读取目录列表
var dirReader = new java.io.BufferedReader(
new java.io.InputStreamReader(dataSocket.getInputStream(), "UTF-8")
);
var files = [];
var line;
while ((line = dirReader.readLine()) !== null) {
if (line.trim()) files.push(line); // 跳过空行
}
// 关闭读取器和Socket
dirReader.close();
dataSocket.close();
dataSocket = null;
// 读取最终响应(226表示传输完成)
sleep.second(0.5);
var finalResp;
while ((finalResp = readResponse()) !== null) {
if (finalResp.startsWith("226 ")) break; // 找到最终的226响应
}
console.log("找到 " + files.length + " 个条目");
return files;
}
/**
* 断开FTP连接
* 关闭所有Socket和流,释放资源
*/
function disconnect() {
try {
// 关闭数据通道
if (dataSocket) {
try { dataSocket.close(); } catch(e) {}
dataSocket = null;
}
// 关闭控制通道
if (controlSocket) {
try {
writer.write("QUIT\r\n"); // 发送QUIT命令
writer.flush();
} catch(e) {}
try { controlSocket.close(); } catch(e) {}
controlSocket = null;
}
// 关闭流
if (reader) { try { reader.close(); } catch(e) {} reader = null; }
if (writer) { try { writer.close(); } catch(e) {} writer = null; }
isConnected = false;
console.log("已断开");
} catch (e) {
// 忽略断开时的错误
}
}
// 公开API - 只暴露这5个方法
return {
connect: connect, // 连接FTP服务器
disconnect: disconnect, // 断开连接
upload: upload, // 上传文件
download: download, // 下载文件
listDir: listDir // 获取目录列表
};
})();
// ==================== 测试代码 ====================
/**
* 主函数 - 演示FTP工具的三个核心功能
* 1. 连接FTP服务器
* 2. 查看目录列表
* 3. 上传文件
* 4. 下载文件
* 5. 断开连接
*/
function main() {
console.log("========== FTP简易工具 ==========\n");
// 1. 连接FTP服务器
if (!FTPClient.connect(FTPConfig)) {
console.log("连接失败");
return;
}
sleep.second(1); // 等待1秒
// 2. 查看根目录文件列表
console.log("\n--- 查看根目录 ---");
var files = FTPClient.listDir("/");
for (var i = 0; i < files.length; i++) {
console.log(" " + files[i]);
}
sleep.second(1); // 等待1秒
// 3. 上传文件测试
console.log("\n--- 上传测试 ---");
FTPClient.upload("/sdcard/test.txt", "/test_upload.txt");
sleep.second(1); // 等待1秒
// 4. 下载文件测试
console.log("\n--- 下载测试 ---");
FTPClient.download("/2.txt", "/sdcard/2_downloaded.txt");
sleep.second(1); // 等待1秒
// 5. 断开连接
FTPClient.disconnect();
console.log("\n========== 完成 ==========");
}
// 执行主函数
main();
复制代码
欢迎光临 自动发帖软件 (http://www.fatiegongju.com/)
Powered by Discuz! X3.2