cycychenyi
4/12/2020 - 12:42 PM

FTP Client 连接示例。

FTP Client 连接示例。

FTP Client 连接示例

注:本示例只说明基本操作,有些具体细节需要自行搜索。

再注:本示例不包括异常检测。

  1. 安装 FileZilla 和 FileZilla Server。
  2. 通过 FileZilla Server Interface 在 FileZilla Server 上添加用户,设置密码(可选),并为其分配共享文件夹。
  3. 在 FileZilla 上使用上一步添加的用户(和密码)快速连接,观察客户端和服务器的控制台信息。
  4. 下载 main.js 和 package.json 文件。在第 5 行和第 6 行填上用户名和密码。如果是连接远程主机的 FTP,还需要把第 4 行的 localhost 修改为主机 IP。运行 npm start,观察 FileZilla Server 的控制台信息。
  5. 学习 main.js 代码,以状态机的方式处理客户端的 FTP 连接,开始编码。
const net = require('net');
let state = 0;
let port = 21;
let host = 'localhost';
let user = '***';
let password = '***';
const controlSocket = net.createConnection({port: port, host: host}, function () {
    console.log('controlSocket 连接到服务器!\n');
});
controlSocket.on('data', function (data) {
    data = data.toString();
    const code = parseInt(data.slice(0, 3));
    switch (state) {
        case 0:
            if (code === 220) {
                // 服务器就绪,可以连接新用户
                controlSocket.write('USER ' + user + '\n');
                state = 1;
            }
            break;
        case 1:
            if (code === 331) {
                // 用户名正确,需要密码
                controlSocket.write('PASS ' + password + '\n');
                state = 2;
            }
            break;
        case 2:
            if (code === 230) {
                // 成功登录
                controlSocket.write('PWD\n');
                state = 3;
            }
            break;
        case 3:
            if (code === 257) {
                // 创建 PATHNAME
                controlSocket.write('PASV\n');
                state = 4;
            }
            break;
        case 4:
            if (code === 227) {
                // 进入被动模式
                const p1 = parseInt(data.split(',')[4]);
                const p2 = parseInt(data.split(',')[5].split(')')[0]);
                const dataSocket = net.createConnection({port: p1 * 256 + p2}, function () {
                    console.log('dataSocket 连接到服务器!\n');
                    controlSocket.write('MLSD\n');
                });
                dataSocket.on('data', function (data) {
                    console.log(data.toString());
                    controlSocket.write('MLSD\n');
                });
            }
            break;
    }
});
{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "main": "main.js",
  "scripts": {
    "start": "node ."
  },
  "author": "",
  "license": "ISC"
}