在这两天被ssh2的shell函数给折磨怕了,我和室友用下面的代码,在一个连接上面连续多次(有时候一百多次,有时候七八百次)执行shell命令就会出现发包丢失,或者根本发命令发不过去的情况,资料又比较少,文档也少,用的人也少,只有去shh2的源码中去看,最后发现ssh2的shell函数返回的stream是一个双工流,然后去nodejs里面去查看关于双工流的介绍,结果试了一些网上介绍的pause和resume函数也没有解决这个问题。我的猜测大概原因是缓冲区堆积的东西太多导致缓冲区爆了之外也有可能是stream再调用end函数之后,将数据发送过去,这个时候缓冲区空了,而远程的机器还没有返回数据过来,导致调用end函数之后直接将stream流自动close了。
function shell(conn, cmd, then) {
conn.shell(function(err, stream) {
if(err) {
then(err);
} else {
var buf = '';
stream.on('close', function() {
then(err, buf);
}).on('data', function(data) {
buf = buf + 'data';
}).stderr.on('data', function(data) {
console.log('stderr :' + data);
});
stream.end(cmd);
}
});
}
在经过多次查找百度、必应寻找问题未果之后,当然也试了各种各样的方法,之后我室友用exec函数试了一下,跑起来轻松愉快无压力,一下子跑个几千几万条命令毫无压力,顿时觉得轻松了许多,虽然还是没有知道shell函数丢包的原因,但总算也找到了一个替代方案,希望知道原因的兄弟能够告知原因。使用exec函数替代shell运行命令代码如下:
function exec(conn, cmd, then) {
conn.exec(cmd, function(err, stream) {
var buf = '';
stream.pipe(through(function onWrite(data){
buf = buf + data;
},function onEnd(){
stream.unpipe();// 一定要关闭
}));
stream.on('close', function() {
then(null, buf);
});
});
}