Ssh Jsch-在单个会话中向SLES15服务器打开多个通道失败

Ssh Jsch-在单个会话中向SLES15服务器打开多个通道失败,ssh,jsch,openssh,sles,Ssh,Jsch,Openssh,Sles,执行命令时,通过在一个会话中打开多个通道到SLES服务器是失败的。此代码适用于所有版本的SLES12、Centos7和Centos8 JSCH版本:0.1.55 SSH服务器计算机详细信息 OS:SUSE Linux企业服务器15 SP2 SSHD:OpenSSH_8.1p1、OpenSSL 1.1.1d 这些是/var/log/messages中的错误: 致命:mm\u应答\u审核\u服务器\u密钥\u空闲:缓冲区错误:消息不完整 致命:mm\U请求\U接收:读取:对等方重置连接 致命:mm\

执行命令时,通过在一个会话中打开多个通道到SLES服务器是失败的。此代码适用于所有版本的SLES12、Centos7和Centos8

JSCH版本:0.1.55

SSH服务器计算机详细信息
OS:SUSE Linux企业服务器15 SP2
SSHD:OpenSSH_8.1p1、OpenSSL 1.1.1d

这些是/var/log/messages中的错误:
致命:mm\u应答\u审核\u服务器\u密钥\u空闲:缓冲区错误:消息不完整
致命:mm\U请求\U接收:读取:对等方重置连接
致命:mm\U请求\U发送:写入:管道断裂

这是JSCH日志中的错误:
信息:连接到10.75.32.47端口22
信息:已建立连接
信息:远程版本字符串:SSH-2.0-OpenSSH_8.1
信息:本地版本字符串:SSH-2.0-JSCH-0.1.54
信息:校验密码:aes256 ctr、aes192 ctr、aes128 ctr、aes256 cbc、aes192 cbc、aes128 cbc、3des ctr、arcfour、arcfour128、arcfour256
信息:复选框:diffie-hellman-group14-sha1、ecdh-sha2-nistp256、ecdh-sha2-nistp384、ecdh-sha2-nistp521
信息:检查签名:ecdsa-sha2-nistp256、ecdsa-sha2-nistp384、ecdsa-sha2-nistp521
信息:SSH\u MSG\u KEXINIT已发送
信息:SSH\u MSG\u KEXINIT收到
信息:kex:服务器:curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1
信息:kex:服务器:rsa-sha2-512、rsa-sha2-256、ssh rsa、ecdsa-sha2-nistp256、ssh-ed25519
信息:kex:服务器:chacha20-poly1305@openssh.com,aes128中心,aes192中心,aes256中心,aes128-gcm@openssh.com,aes256-gcm@openssh.com
信息:kex:服务器:chacha20-poly1305@openssh.com,aes128中心,aes192中心,aes256中心,aes128-gcm@openssh.com,aes256-gcm@openssh.com
信息:kex:服务器:umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1
信息:kex:服务器:umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1
信息:kex:服务器:无,zlib@openssh.com
信息:kex:服务器:无,zlib@openssh.com
信息:kex:服务器:
信息:kex:服务器:
信息:kex:客户:ecdh-sha2-nistp256、ecdh-sha2-nistp384、ecdh-sha2-nistp521、diffie-hellman-group14-sha1、diffie-hellman-group-exchange-sha256、diffie-hellman-group-exchange-sha1、diffie-hellman-group1-sha1
信息:kex:客户端:ssh rsa、ssh dss、ecdsa-sha2-nistp256、ecdsa-sha2-nistp384、ecdsa-sha2-nistp521
信息:kex:客户:aes128 ctr、aes128 cbc、3des ctr、3des cbc、河豚cbc、aes192 ctr、aes192 cbc、aes256 ctr、aes256 cbc
信息:kex:客户:aes128 ctr、aes128 cbc、3des ctr、3des cbc、河豚cbc、aes192 ctr、aes192 cbc、aes256 ctr、aes256 cbc
信息:kex:客户:hmac-md5、hmac-sha1、hmac-sha2-256、hmac-sha1-96、hmac-md5-96
信息:kex:客户:hmac-md5、hmac-sha1、hmac-sha2-256、hmac-sha1-96、hmac-md5-96
信息:kex:客户:无
信息:kex:客户:无
信息:kex:客户:
信息:kex:客户:
信息:kex:服务器->客户端aes128 ctr hmac-sha1无
信息:kex:客户端->服务器aes128 ctr hmac-sha1无
信息:SSH\u MSG\u KEX\u ECDH\u INIT已发送
信息:期待SSH\u MSG\u KEX\u ECDH\u回复
信息:ssh\u rsa\u验证:签名为真
警告:已将“10.75.32.47”(RSA)永久添加到已知主机列表中。
信息:SSH\u MSG\u已发送新密钥
信息:收到SSH\u MSG\u新密钥
信息:SSH\u消息\u服务\u请求已发送
信息:收到SSH\u消息\u服务\u接受
信息:可以继续的身份验证:公钥、键盘交互、密码
信息:下一个身份验证方法:公钥
信息:可以继续的身份验证:键盘交互,密码
信息:下一个身份验证方法:键盘交互
信息:身份验证成功(键盘交互)。
正在等待所有任务完成…
信息:捕获到异常,由于连接重置而离开主循环
信息:从10.75.32.47端口22断开连接

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;

public class SSHTest {

    public static void main(String[] args) {
        try {
            JSch jsch = new JSch();
            Session session = jsch.getSession("userName", "hostAddress", 22);
            String command = "echo \"Hi\" && sleep 1";
            java.util.Properties config = new java.util.Properties();
            config.put("StrictHostKeyChecking", "no");
            config.put("PreferredAuthentications","publickey,keyboard-interactive,password");
            session.setConfig(config);
            session.setPassword("david");
            session.setTimeout(60000);

            session.connect();

            ExecutorService channelsPool = Executors.newFixedThreadPool(4);
            
            for (int i = 0; i < 4; i++) {
                channelsPool.execute(new TaskExecutor(command, session));
            }

            System.out.println("Waiting for all tasks to finish...");
            channelsPool.shutdown(); // Disable new tasks from being submitted
            try {
                // Wait a while for existing tasks to terminate
                if (!channelsPool.awaitTermination(60, TimeUnit.SECONDS)) {
                    channelsPool.shutdownNow(); // Cancel currently executing tasks
                    // Wait a while for tasks to respond to being cancelled
                    if (!channelsPool.awaitTermination(60, TimeUnit.SECONDS))
                        System.err.println("Pool did not terminate");
                } else {
                    System.out.println("All tasks finished successfully");
                }
            } catch (InterruptedException ie) {
                // (Re-)Cancel if current thread also interrupted
                channelsPool.shutdownNow();
                // Preserve interrupt status
                Thread.currentThread().interrupt();
            }

            session.disconnect();

            System.out.println("************************* Execution completed *************************");
        } catch (JSchException e) {
            e.printStackTrace();
        }
    }

}
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
导入java.util.concurrent.TimeUnit;
导入com.jcraft.jsch.jsch;
导入com.jcraft.jsch.JSchException;
导入com.jcraft.jsch.Session;
公共类SSHTest{
公共静态void main(字符串[]args){
试一试{
JSch JSch=新的JSch();
Session Session=jsch.getSession(“用户名”,“主机地址”,22);
String command=“echo\”Hi\”和&sleep 1”;
java.util.Properties config=new java.util.Properties();
配置放置(“检查”、“否”);
config.put(“首选身份验证”、“公钥、键盘交互、密码”);
session.setConfig(config);
session.setPassword(“david”);
会话设置超时(60000);
session.connect();
ExecutorService channelsPool=Executors.newFixedThreadPool(4);
对于(int i=0;i<4;i++){
channelsPool.execute(新任务执行器(命令,会话));
}
System.out.println(“等待所有任务完成…”);
channelsPool.shutdown();//禁止提交新任务
试一试{
//请等待现有任务终止
如果(!channelsPool.waiting终止(60,时间单位秒)){
channelsPool.shutdownow();//取消当前

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.ArrayList;

import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;

public class TaskExecutor implements Runnable {

    private String command;
    private Session session;

    public TaskExecutor(String command, Session session) {
        this.command = command;
        this.session = session;
    }

    @Override
    public void run() {
        try {
            execute();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void execute() throws JSchException, IOException {
        ChannelExec channelExec = (ChannelExec) session.openChannel("exec");
        channelExec.setCommand(command);
        InputStream inputStream = channelExec.getInputStream();
        InputStream errorStream = channelExec.getErrStream();
        OutputStream outputStream = channelExec.getOutputStream();
        channelExec.connect();
        int exitCode = channelExec.getExitStatus();

        ArrayList<String> output = new ArrayList<>();
        ArrayList<String> error = new ArrayList<>();
        try (BufferedReader outputReader = new BufferedReader(new InputStreamReader(inputStream));
                BufferedReader errorReader = new BufferedReader(new InputStreamReader(errorStream))) {
            boolean isDataLeftInStream = true;
            // Read data in output stream
            while (isDataLeftInStream) {
                String line = outputReader.readLine();
                if (line != null) {
                    output.add(line);
                } else {
                    isDataLeftInStream = false;
                }
            }

            // Read data in error stream
            isDataLeftInStream = true;
            while (isDataLeftInStream) {
                String line = errorReader.readLine();
                if (line != null) {
                    error.add(line);
                } else {
                    isDataLeftInStream = false;
                }
            }
        }
        
        channelExec.disconnect();

        System.out.println("Execution Result: \n\tExitCode=" + exitCode + "\n\tOutput=" + String.join("\n", output)
                + "\n\tError=" + String.join("\n", error));
    }

}