通信过程

FTP协议其实就是主机和服务通过Socket进行固定格式的通信过程,当某客户端连接到FTP 服务器后,客户端发送指令: [参数]

服务会按以下格式返回: [参数或说明]

例如以下是FileZilla FTP客户端与服务器通信的过程:

"命令"为客户端通过socket发送的消息,“响应”为服务器端的返回响应: 220-FileZilla Server version 0.9.43 beta

响应: 220-written by Tim Kosse (tim.kosse@filezilla-project.org)

响应: 220 Please visit http://sourceforge.net/projects/filezilla/

命令: AUTH TLS

响应: 502 SSL/TLS authentication not allowed

命令: AUTH SSL

响应: 502 SSL/TLS authentication not allowed

命令: USER newghost

响应: 331 Password required for newghost

命令: PASS **************

响应: 230 Logged on

命令: SYST

响应: 215 UNIX emulated by FileZilla

命令: FEAT

响应: 211-Features:

响应: MDTM

响应: REST STREAM

响应: SIZE

响应: MLST type*;size*;modify*;

响应: MLSD

响应: UTF8

响应: CLNT

响应: MFMT

响应: 211 End

命令: PWD

响应: 257 "/" is current directory.

命令: TYPE I

响应: 200 Type set to I

命令: PASV

响应: 227 Entering Passive Mode (121,42,140,131,14,77)

命令: MLSD

响应: 150 Opening data channel for directory listing of "/"

响应: 226 Successfully transferred "/"

以下是FTP中的命令列表{

"ABOR": "Abort an active file transfer.",

"ACCT": "Account information.",

"ADAT": "Authentication/Security Data",

"ALLO": "Allocate sufficient disk space to receive a file.",

"APPE": "Append.",

"AUTH": "Authentication/Security Mechanism",

"CCC": "Clear Command Channel",

"CDUP": "Change to Parent Directory.",

"CONF": "Confidentiality Protection Command",

"CWD": "Change working directory.",

"DELE": "Delete file.",

"ENC": "Privacy Protected Channel",

"EPRT": "Specifies an extended address and port to which the server should connect.",

"EPSV": "Enter extended passive mode.",

"FEAT": "Get the feature list implemented by the server.",

"HELP": "Returns usage documentation on a command if specified, else a general help document is returned.",

"HOST": "Identify desired virtual host on server, by name.",

"LANG": "Language Negotiation",

"LIST": "Returns information of a file or directory if specified, else information of the current working directory is returned.",

"LPRT": "Specifies a long address and port to which the server should connect.",

"LPSV": "Enter long passive mode.",

"MDTM": "Return the last-modified time of a specified file.",

"MFCT": "Modify the creation time of a file.",

"MFF": "Modify fact (the last modification time, creation time, UNIX group/owner/mode of a file).",

"MFMT": "Modify the last modification time of a file.",

"MIC": "Integrity Protected Command",

"MKD": "Make directory.",

"MLSD": "Lists the contents of a directory if a directory is named.",

"MLST": "Provides data about exactly the object named on its command line, and no others.",

"MODE": "Sets the transfer mode (Stream, Block, or Compressed).",

"NLST": "Returns a list of file names in a specified directory.",

"NOOP": "No operation (dummy packet; used mostly on keepalives).",

"OPTS": "Select options for a feature (for example OPTS UTF8 ON).",

"PASS": "Authentication password.",

"PASV": "Enter passive mode.",

"PBSZ": "Protection Buffer Size",

"PORT": "Specifies an address and port to which the server should connect.",

"PROT": "Data Channel Protection Level.",

"PWD": "Print working directory. Returns the current directory of the host.",

"QUIT": "Disconnect.",

"REIN": "Re initializes the connection.",

"REST": "Restart transfer from the specified point.",

"RETR": "Retrieve a copy of the file",

"RMD": "Remove a directory.",

"RNFR": "Rename from.",

"RNTO": "Rename to.",

"SITE": "Sends site specific commands to remote server (like SITE IDLE 60 or SITE UMASK 002). Inspect SITE HELP output for complete list of supported commands.",

"SIZE": "Return the size of a file.",

"SMNT": "Mount file structure.",

"SPSV": "Use single port passive mode (only one TCP port number for both control connections and passive-mode data connections)",

"STAT": "Returns the current status.",

"STOR": "Accept the data and to store the data as a file at the server site",

"STOU": "Store file uniquely.",

"STRU": "Set file transfer structure.",

"SYST": "Return system type.",

"TYPE": "Sets the transfer mode (ASCII/Binary).",

"USER": "Authentication username.",

"XCUP": "Change to the parent of the current working directory",

"XMKD": "Make a directory",

"XPWD": "Print the current working directory",

"XRCP": "",

"XRMD": "Remove the directory",

"XRSQ": "",

"XSEM": "Send, mail if cannot",

"XSEN": "Send to terminal"

}

以下是FTP中的返回状态码列表:var REPLY_CODE = {

"110": "Restart marker reply.",

"120": "Service ready in nn minutes.",

"125": "Data Connection already open; transfer starting.",

"150": "File status okay; about to open data connection.",

"200": "Command okay.",

"202": "Command not implemented, superfluous at this site.",

"211": "System status, or system help reply.",

"212": "Directory status.",

"213": "File status.",

"214": "Help message.",

"215": "NAME system type.",

"220": "Service ready for new user.",

"221": "Service closing control connection.",

"225": "Data connection open; no transfer in progress.",

"226": "Closing data connection.",

"227": "Entering Passive Mode.",

"230": "User logged in, proceed. This status code appears after the client sends the correct password. It indicates that the user has successfully logged on.",

"250": "Requested file action okay, completed.",

"257": "'\"'PATHNAME'\"' created.",

"331": "User name okay, need password.",

"332": "Need account for login.",

"350": "Requested file action pending further information.",

"421": "Error 421 Service not available, closing control connection.\n Error 421 User limit reached\n Error 421 You are not authorized to make the connection\n Error 421 Max connections reached\n Error 421 Max connections exceeded",

"425": "Cannot open data connection.",

"426": "Connection closed; transfer aborted.",

"450": "Requested file action not taken.",

"451": "Requested action aborted: local error in processing.",

"452": "Requested action not taken. Insufficient storage space in system.",

"500": "Syntax error, command unrecognized, command line too long.",

"501": "Syntax error in parameters or arguments.",

"502": "Command not implemented.",

"503": "Bad sequence of commands.",

"504": "Command not implemented for that parameter.",

"530": "User not logged in.",

"532": "Need account for storing files.",

"550": "Requested action not taken. File unavailable, not found, not accessible",

"552": "Requested file action aborted. Exceeded storage allocation.",

"553": "Requested action not taken. File name not allowed.",

"10054": "Connection reset by peer. The connection was forcibly closed by the remote host.",

"10060": "Cannot connect to remote server.",

"10061": "Cannot connect to remote server. The connection is actively refused by the server.",

"10066": "Directory not empty.",

"10068": "Too many users, server is full."

}

一个简易的FTP服务器

通过以上协议,我们可以编写一个简易的实现了登陆过程的FTP服务器,var net = require('net')

var COMMANDS = {

AUTH: function() {

this.send('502 SSL/TLS authentication not allowed.')

},

USER: function(username) {

this.session.username = username

this.send('331 User name okay, need password.')

},

PASS: function(password) {

var socket = this

var username = socket.username

if (username == 'newghost' && password == 'dachun') {

socket.send(230, 'Logged on')

} else {

socket.send(450, 'Ensure that you typed the correct user name and password combination.')

}

},

PWD: function(args) {

this.send('257 "/" is current directory')

},

TYPE: function(args) {

this.send('200 Type set to I')

},

EPSV: function(args) {

this.send('229 Entering Extended Passive Mode (|||30324|).')

},

PASV: function(args) {

this.send('227 Entering Passive Mode (112,124,126,185,165,12).')

},

MLSD: function(args) {

this.send('226 Successfully transferred "/"')

},

LIST: function(args) {

this.send('502 Command not implemented.')

this.send('502')

}

}

var sendHandler = function(type, message) {

var socket = this

var command

if (arguments.length < 2) {

if (REPLY_CODE[type]) {

command = REPLY_CODE[type]

} else {

command = type.toString()

}

} else {

command = type + ' ' + message

}

console.log('S:', command)

socket.write(command + '\r\n')

}

var ftpServer = net.createServer(function(socket) {

socket.session = {}

socket.send = sendHandler

socket.send(220, 'Welcome to OnceDoc FTP Server')

var onCommand = function(buffer) {

//receives.push(data)

//var buffer = Buffer.concat(receives).toString()

//receives = []

var buffers = buffer.toString()

var lines = buffers.split('\r\n')

for (var i = 0, l = lines.length; i < l; i++) {

var line = lines[i]

if (line) {

console.log('C:', line)

//lines.push(raw[i])

var cmds = line.split(' ')

var cmd = cmds[0].toUpperCase()

var arg = cmds.slice(1)

var func = COMMANDS[cmd]

func

? func.apply(socket, arg)

: socket.send(502)

}

}

}

socket

.on('data', onCommand)

.on('end', function() {

console.log('end', arguments)

})

.on('close', function () {

console.log('close', arguments)

})

.on('timeout', function () {

console.log('timeout', arguments)

})

.on('error', function (err) {

console.log('error', arguments)

})

}).on('error', function(err) {

// handle errors here

console.error(err)

})

//

ftpServer.listen({ port: 21 }, function() {

console.log('opened server on', ftpServer.address())

})

FTP 服务器端模块

目前用Node.JS实现的服务端模块还不多,大多不是很成熟,如

ftp-srvconst FtpSvr = require('ftp-srv')

const ftpServer = new FtpSvr('ftp://127.0.0.1:21')

ftpServer.on('login', function (data, resolve, reject) {

var connection = data.connection

var username = data.username

var password = data.password

if (data.username == 'anonymous') {

resolve({ root: 'D:\\github\\oncedoc\\onceoa' })

} else {

reject()

}

})

ftpServer

.listen()

.then(() => {

console.log('ready')

})

ftpServervar FTPServer = require('ftpserver').FTPServer

var ftpServer = new FTPServer({

host: '127.0.0.1',

port: 21,

pasvStart: null,

pasvEnd: null,

timeout: 30000,

disabledCommands: [],

anonymous: false,

logLevel: 10,

greeting: null,

override: {

fs: null,

authentication: null

}

})

ftpServer.listen().then(() => {

})

nodeftpd

FTP 客户端模块

目前基于node.js的FTP客户端非常成熟,开源项目也比较多

JSFTPvar JSFtp = require("jsftp");

var Ftp = new JSFtp({

host: "myserver.com",

port: 3331, // defaults to 21

user: "user", // defaults to "anonymous"

pass: "1234" // defaults to "@anonymous"

});

Ftp.raw("mkd", "/new_dir", function(err, data) {

if (err) return console.error(err);

console.log(data.text); // Show the FTP response text to the user

console.log(data.code); // Show the FTP response code to the user

});

node-ftpvar c = new Client();

c.on('ready', function() {

c.list(function(err, list) {

if (err) throw err;

console.dir(list);

c.end();

});

});

// connect to localhost:21 as anonymous

c.connect();

node-ftps

这个项目是对lftp的node.js封装var FTPS = require('ftps');

var ftps = new FTPS({

host: 'domain.com', // required

username: 'Test', // Optional. Use empty username for anonymous access.

password: 'Test', // Required if username is not empty, except when requiresPassword: false

protocol: 'sftp', // Optional, values : 'ftp', 'sftp', 'ftps', ... default: 'ftp'

// protocol is added on beginning of host, ex : sftp://domain.com in this case

port: 22, // Optional

// port is added to the end of the host, ex: sftp://domain.com:22 in this case

escape: true, // optional, used for escaping shell characters (space, $, etc.), default: true

retries: 2, // Optional, defaults to 1 (1 = no retries, 0 = unlimited retries)

timeout: 10, // Optional, Time before failing a connection attempt. Defaults to 10

retryInterval: 5, // Optional, Time in seconds between attempts. Defaults to 5

retryMultiplier: 1, // Optional, Multiplier by which retryInterval is multiplied each time new attempt fails. Defaults to 1

requiresPassword: true, // Optional, defaults to true

autoConfirm: true, // Optional, is used to auto confirm ssl questions on sftp or fish protocols, defaults to false

cwd: '', // Optional, defaults to the directory from where the script is executed

additionalLftpCommands: '', // Additional commands to pass to lftp, splitted by ';'

requireSSHKey: true, // Optional, defaults to false, This option for SFTP Protocol with ssh key authentication

sshKeyPath: '/home1/phrasee/id_dsa' // Required if requireSSHKey: true , defaults to empty string, This option for SFTP Protocol with ssh key authentication

});

// Do some amazing things

ftps.cd('some_directory').addFile(__dirname + '/test.txt').exec(console.log);

js ftpclient linux server,Node.JS用Socket实现FTP Server服务器和Client客户端相关推荐

  1. Linux部署Node.js应用

    Linux部署Node.js应用 文章目录 Linux部署Node.js应用 一.背景描述 二.环境准备 三.添加守护进程 四.参考链接 一.背景描述 将基于Node.js开发的应用部署到Linux系 ...

  2. Linux 创建网页服务,Linux使用Node.js建立访问静态网页的服务实例详解

    Linux使用Node.js建立访问静态网页的服务实例详解 一.安装node.js运行所需要的环境,: 二.创建node目录(/node/www),并在目录下创建node.js服务文件server.j ...

  3. js写的程序如何上线到linux,将 Node.js 应用发布到 Linux 应用服务 - Visual Studio | Microsoft Docs...

    将 Node.js 应用程序发布到 Azure(Linux 应用服务)Publish a Node.js application to Azure (Linux App Service) 11/22/ ...

  4. centos/linux 安装node.js

    默认系统自带的2.4,版本过低,这里直接安装最新版本2.7 wget  http://www.python.org/ftp/python/2.7/Python-2.7.tar.bz2 tar jfvx ...

  5. Node.js与网络:Node.js对TCP、UDP、Socket、HTTP等协议的实现和支持

    转自:https://itbilu.com/nodejs/core/VkcdcFq9.html OSI七层模型是不同计算机或通信系统间互联的标准体系和框架,在OSI中包括一系列标准和协议,如:TCP/ ...

  6. linux安装Node.js(详细)Node.js安装教程

    linux安装Node.js(详细)Node.js安装教程 文章目录 linux安装Node.js(详细)Node.js安装教程 1:下载 2:解压 3:移动目录 1:创建目录 2:移动目录并重命名 ...

  7. linux安装Node.js 详细安装教程

    linux安装Node.js 操作步骤 1. 下载并解压(本文以14为例) 下载 wget https://nodejs.org/dist/v14.17.4/node-v14.17.4-linux-x ...

  8. linux node 命令无效,完美解决linux下node.js全局模块找不到的情况

    今天在在linux上用npm安装了pm2准备部署node项目,结果通过pm2命令启动项目的时候报pm2找不到,这很伤,以为pm2没有安装成功,但是在node安装目录下面的bin文件夹里面调用pm2却没 ...

  9. 【深入浅出Node.js系列十一】Node.js开发框架Express4.x

    为什么80%的码农都做不了架构师?>>>    #0 系列目录# 深入浅出Node.js系列 [深入浅出Node.js系列一]什么是Node.js [深入浅出Node.js系列二]N ...

  10. node.js入门系列(一)--Node.js简介

    什么是NodeJS JS是脚本语言,脚本语言都需要一个解析器才能运行.对于写在HTML页面里的JS,浏览器充当了解析器的角色.而对于需要独立运行的JS,NodeJS就是一个解析器. 每一种解析器都是一 ...

最新文章

  1. PHP问题 —— Deprecated: Function ereg_replace() is de
  2. mysql sql 1到10_(1.10)SQL优化——mysql 常见SQL优化
  3. matlab txt写入excel,怎么把matlab的GUI文本编辑器中的数据存入EXCEl
  4. 用户偏好类结构化数据分析题参赛总结
  5. RabbitMQ负载均衡(4)——LVS
  6. mysql语句数据库_数据库的Mysql语句
  7. Opencv ORC——文字定位与切割
  8. cross-env使用 1
  9. QT中foreach的使用
  10. 安卓手机运行ios教程_英雄联盟手游日服怎么注册?安卓/ios注册下载教程! 18183手机游戏网...
  11. python 实现随机加减法
  12. python画气泡图_画气泡图的十二个图表库
  13. 汉码科技仓储管理信息化解决方案,助力生产企业提升仓储管理水平,提升企业竞争力,提升产品形象
  14. 贪吃蛇c语言中加速怎么写,刚学C语言,想写一个贪吃蛇的代码
  15. OpenCV图像的基本操作
  16. 游戏中的脚本语言原理与发展
  17. Alibaba内部Java技术成长笔记,业界良心,程序员最爱
  18. 小米从北京迁往武汉南京,一线大厂逃离或为新常态?
  19. 无标注数据是鸡肋还是宝藏?阿里工程师这样用它
  20. 数夫家具MES制造执行系统,助力家具行业打造家具智能制造车

热门文章

  1. 将代码生成器带入TVM
  2. 超轻量AI引擎MindSpore Lite
  3. 将视频插入视频:CVPR2019论文解析
  4. 2021年大数据常用语言Scala(十四):基础语法学习 数组  重点掌握
  5. 高并发下接口幂等性技术方案
  6. [C] Bellman-Ford边松弛:解决负权边
  7. 微信小程序模板template
  8. sprintf 和strcpy 的差别
  9. 打字游戏--飞机大战
  10. FhqTreap的区间翻转