arunan
arunan

Reputation: 951

inputstream make the program to wait

I am using J2ssh library to connect to a Unix machine, run a command and get the result using input stream. But the programs runs into loop while reading the input stream. I am able to get the result from the input steam, but the program struck there and not proceeding. Why is the program stuck in that loop?

Here is the source code,

public void loginAndCheckProcess(String hostName, String userName, String password, String port) {
        try {
            SshConnector con = SshConnector.createInstance();

            SocketTransport transport = new SocketTransport(hostName, 22);
            transport.setTcpNoDelay(true);
            SshClient client = con.connect(transport, userName);

            Ssh2Client ssh2 = (Ssh2Client) client;

            PasswordAuthentication pwd = new PasswordAuthentication();
            do {
                pwd.setPassword(password);
            } while (ssh2.authenticate(pwd) != SshAuthentication.COMPLETE && client.isConnected());

            String command = "ps -ef | grep " + port + '\n';
            if (client.isAuthenticated()) {
                SshSession session = client.openSessionChannel();
                session.startShell();
                session.getOutputStream().write(command.getBytes());
                InputStream is = session.getInputStream();
                Scanner br = new Scanner(new InputStreamReader(is));

                String line = null;
                int isRunning = 0;
                while (br.hasNextLine()) {
                    line = br.nextLine();
                    isRunning++;
                    System.out.println(line);
                }
                session.close();
            }
        } catch (SshException | IOException | ChannelOpenException ex) {
            Logger.getLogger(Authenticator.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

I tried to replace the above second while loop with the following loop but no luck,

try (Reader in = new InputStreamReader(is, "UTF-8")) {
                    for (;;) {
                        int rsz = in.read(buffer, 0, buffer.length);
                        if (rsz < 0)
                            break;
                        out.append(buffer, 0, rsz);
                    }
                }
                System.out.println(out);

And with the following loop, but no luck,

byte[] tmp = new byte[1024];
                while (is.available() > 0) {
                    int i = is.read(tmp, 0, 1024);
                    if (i < 0) {
                        break;
                    }
                    System.out.print(new String(tmp, 0, i));
                }

Upvotes: 0

Views: 1283

Answers (2)

Lee David Painter
Lee David Painter

Reputation: 510

Your code will keep looping on the session InputStream until the session closes i.e. the InputStream returns EOF. As you used startShell method, this spawns an interactive shell so the session will continue and present a new prompt after your command has executed, awaiting another command.

You could add a call to exit in your command

String command = "ps -ef | grep " + port + ';exit\n';

Or you could use the alternative executeCommand method on the session rather than writing out the command to the OutputStream.

session.executeCommand(command);

Upvotes: 0

arunan
arunan

Reputation: 951

At last I found the answer, thank you mangusta.

I have added timeout on the socket. It worked. I just added below line in the program,

transport.setSoTimeout(3000);

Upvotes: 1

Related Questions