Я пытаюсь написать письмо ftp-клиента против Filezilla, поддерживающего активный режим с помощью node.js. Я новичок в ftp и node.js. Я думал, что смогу хорошо понять связь с tcp-сокетом и протокол ftp, выполнив это упражнение. Кроме того, node-ftp a jsftp, похоже, не поддерживают активный режим, поэтому я думаю, что это будет приятное (хотя и редко используемое) дополнение к npm.Активный FTP-клиент для Node.js
У меня есть некоторые доказательства кода концепции, который работает хотя бы иногда, но не все время. В случае, когда он работает, клиент загружает файл с именем file.txt
с текстом «привет». Когда он работает, я получаю это:
220-FileZilla Server version 0.9.41 beta
220-written by Tim Kosse ([email protected])
220 Please visit http://sourceforge.net/projects/filezilla/
331 Password required for testuser
230 Logged on
listening
200 Port command successful
150 Opening data channel for file transfer.
server close
226 Transfer OK
half closed
closed
Process finished with exit code 0
Когда он не работает, я получаю это:
220-FileZilla Server version 0.9.41 beta
220-written by Tim Kosse ([email protected])
220 Please visit http://sourceforge.net/projects/filezilla/
331 Password required for testuser
230 Logged on
listening
200 Port command successful
150 Opening data channel for file transfer.
server close
half closed
closed
Process finished with exit code 0
Таким образом, я не получаю 226, и я не уверен, почему я получаю непоследовательные результаты.
Простите плохо написанный код. Я рефакторинга, когда я уверен, что я понимаю, как это должно работать .:
var net = require('net'),
Socket = net.Socket;
var cmdSocket = new Socket();
cmdSocket.setEncoding('binary')
var server = undefined;
var port = 21;
var host = "localhost";
var user = "testuser";
var password = "Password1*"
var active = true;
var supplyUser = true;
var supplyPassword = true;
var supplyPassive = true;
var waitingForCommand = true;
var sendFile = true;
function onConnect(){
}
var str="";
function onData(chunk) {
console.log(chunk.toString('binary'));
//if ftp server return code = 220
if(supplyUser){
supplyUser = false;
_send('USER ' + user, function(){
});
}else if(supplyPassword){
supplyPassword = false;
_send('PASS ' + password, function(){
});
}
else if(supplyPassive){
supplyPassive = false;
if(active){
server = net.createServer(function(socket){
console.log('new connection');
socket.setKeepAlive(true, 5000);
socket.write('hi', function(){
console.log('write done');
})
socket.on('connect', function(){
console.log('socket connect');
});
socket.on('data', function(d){
console.log('socket data: ' + d);
});
socket.on('error', function(err){
console.log('socket error: ' + err);
});
socket.on('end', function() {
console.log('socket end');
});
socket.on('drain', function(){
console.log('socket drain');
});
socket.on('timeout', function(){
console.log('socket timeout');
});
socket.on('close', function(){
console.log('socket close');
});
});
server.on('error', function(e){
console.log(e);
});
server.on('close', function(){
console.log('server close');
});
server.listen(function(){
console.log('listening');
var address = server.address();
var port = address.port;
var p1 = Math.floor(port/256);
var p2 = port % 256;
_sendCommand('PORT 127,0,0,1,' + p1 + ',' + p2, function(){
});
});
}else{
_send('PASV', function(){
});
}
}
else if(sendFile){
sendFile = false;
_send('STOR file.txt', function(){
});
}
else if(waitingForCommand){
waitingForCommand = false;
cmdSocket.end(null, function(){
});
if(server)server.close(function(){});
}
}
function onEnd() {
console.log('half closed');
}
function onClose(){
console.log('closed');
}
cmdSocket.once('connect', onConnect);
cmdSocket.on('data', onData);
cmdSocket.on('end', onEnd);
cmdSocket.on('close', onClose);
cmdSocket.connect(port, host);
function _send(cmd, callback){
cmdSocket.write(cmd + '\r\n', 'binary', callback);
}
Кроме того, это server
подходит, или я должен сделать это какой-то другой способ?
EDIT: Я изменил обратный вызов в server.listen, чтобы использовать случайный порт. Это удалило 425, которые я получал ранее. Тем не менее, я все еще не получаю согласованное поведение с передачей файлов.
Вы проверили это? https://github.com/sergi/jsftp. – yeya