2017-07-14 167 views
0

我已經創建了一個基於節點的SSH2 SFTP服務器和客戶端。我的目標是讀取SFTP服務器的目錄結構。假設我有一個包含temp文件夾的SFTP服務器,我想讀取temp目錄內的文件。我使用ssh2 npm模塊來創建SFTP服務器和客戶端。它正在連接SFTP服務器,但沒有列出該目錄使用節點js讀取目錄的SFTP服務器

下面是代碼

客戶端SFTP

var Client = require('ssh2').Client; 
 
var connSettings = { 
 
    host: 'localhost', 
 
    port: 22, 
 
    username:'ankit', 
 
    password:'shruti', 
 
    method:'password' 
 

 
    // You can use a key file too, read the ssh2 documentation 
 
}; 
 

 
var conn = new Client(); 
 
conn.on('ready', function() { 
 

 
console.log("connected to sftp server") 
 

 
conn.sftp(function(err, sftp) { 
 
     if (err) 
 
     throw err; 
 

 
     sftp.readdir('',function(err,list) 
 
     { 
 

 
      console.log('Inside read') 
 
      if(err) 
 
      { 
 
      console.log(err);  
 
      throw err; 
 
      } 
 
      console.log('showing directory listing') 
 
      console.log(list); 
 
      conn.end(); 
 

 
     }) 
 

 

 
     /** 
 
     var moveFrom = "/remote/file/path/file.txt"; 
 
     var moveTo = __dirname+'file1.txt'; 
 

 
     sftp.fastGet(moveFrom, moveTo , {}, function(downloadError){ 
 
      if(downloadError) throw downloadError; 
 

 
      console.log("Succesfully uploaded"); 
 
     }); 
 
     */ 
 
}) 
 

 
}).connect(connSettings);

SERVER SIDE SFTP : 
 

 
var constants = require('constants'); 
 
var fs = require('fs'); 
 

 
var ssh2 = require('ssh2'); 
 
var OPEN_MODE = ssh2.SFTP_OPEN_MODE; 
 
var STATUS_CODE = ssh2.SFTP_STATUS_CODE; 
 

 
var srv = new ssh2.Server({ 
 
    hostKeys: [fs.readFileSync(__dirname+'/key/id_rsa')],debug:console.log 
 
}, function(client) { 
 
    console.log('Client connected!'); 
 
    client.on('authentication', function(ctx) { 
 
    if (ctx.method === 'password' 
 
     // Note: Don't do this in production code, see 
 
     // https://www.brendanlong.com/timing-attacks-and-usernames.html 
 
     // In node v6.0.0+, you can use `crypto.timingSafeEqual()` to safely 
 
     // compare two values. 
 
     && ctx.username === 'ankit' 
 
     && ctx.password === 'shruti') 
 
     ctx.accept(); 
 
    else 
 
     ctx.reject(); 
 
    }).on('ready', function() { 
 
    console.log('Client authenticated!'); 
 
    }); 
 

 
    client.on('session',function(accept,reject) 
 
    { 
 
     console.log("Client asking for session"); 
 
     var session = accept(); 
 
     var handleCount = 0; 
 
     var names=[] 
 

 
     session.on('sftp',function(accept,reject) 
 
     { 
 
      console.log('Client sftp connection') 
 
      var sftpStream = accept(); 
 

 
      sftpStream.on('OPENDIR',function(reqID,path) 
 
      { 
 
      var handle = new Buffer(4); 
 
      handle.writeUInt32BE(handleCount++, 0, true); 
 
      sftpStream.handle(reqID,handle); 
 
      console.log(handle); 
 
      console.log('Opening Read Directory for --'+path); 
 
      console.log(reqID); 
 
      console.log(path); 
 

 
      }).on('READDIR',function(reqID,handle) 
 
      { 
 
      console.log('Read request') 
 
      console.log(reqID); 
 
      if(handle.length!==4) 
 
      return sftpStream.status(reqID, STATUS_CODE.FAILURE,'There was failure') 
 
      
 
       sftpStream.status(reqID, STATUS_CODE.OK,'Everything ok') 
 
       sftpStream.name(reqID,names);  
 
       
 
       
 
      }) 
 
      
 

 

 
     }) 
 

 

 
    }) 
 

 
    
 

 

 

 

 

 

 
}).listen(0, '127.0.0.1', function() { 
 
    console.log('Listening on port ' + this.address().port); 
 
}); 
 

 
srv.listen(22)

回答

0

客戶端將發送多個READDIR請求。在第一次請求時,您應該發送文件列表,第二次您應該發送EOF狀態,以告訴客戶列表已完成。

一個例子是:

let listSent = false; 
let names = []; 

sftpStream.on('OPENDIR', function (reqID, path) { 
    listSent = false; 
    sftpStream.handle(new Buffer()); 
}); 

sftpStream.on('READDIR', function (reqID, handle) { 
    if (listSent) { 
     sftpStream.status(reqID, STATUS_CODE.EOF); 
     return; 
    } 

    sftpStream.name(reqID, names); 
    listSent = true; 
});