Prasad Khode
Prasad Khode

Reputation: 6739

Automated Telnet client using commons-net

My requirement is to connect to some server through telnet using a java program and run few commands and read the responses. Based on these responses I need to perform some operation

I strated with https://stackoverflow.com/a/1213188/1025328

I'm using commons-net and my program is something like this:

public class TelnetSample {
    private TelnetClient telnet;
    private InputStream in;
    private PrintStream out;

    public TelnetSample(String server, int port) {
        try {
            // Connect to the specified server
            telnet = new TelnetClient();
            telnet.connect(server, port);

            in = telnet.getInputStream();
            out = new PrintStream(telnet.getOutputStream());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public String readResponse() {
        System.out.println("TelnetSample.readResponse()");

        StringBuilder out = new StringBuilder();

        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            String line;
            while ((line = reader.readLine()) != null) {
                out.append(line);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        System.out.println(out.toString());
        System.out.println("==========================================================");

        return out.toString();
    }

    public String read2() {
        System.out.println("TelnetSample.read()");

        StringBuffer sb = new StringBuffer();

        try {
            int available = in.available();

            for (int index = 0; index < available; index++) {
                char ch = (char) in.read();
                System.out.print(ch);
                sb.append(ch);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return sb.toString();
    }

    public String sendCommand(String command) {
        try {
            InputStream is = new ByteArrayInputStream(command.getBytes());

            int ch;

            while ((ch = is.read()) != -1) {
                out.write(ch);
                out.flush();
            }

            System.out.println(command);

            String output = read2();

            if (output.trim().isEmpty()) {
                System.out.println("output empty");
            } else {
                System.out.println(output);
            }

            System.out.println("==========================================================");

            return output;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    public void disconnect() {
        try {
            telnet.disconnect();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        try {
            TelnetSample telnet = new TelnetSample("aspmx2.xxxxxx.com", 25);
            telnet.readResponse();

            telnet.sendCommand("Helo hi");
            telnet.sendCommand("mail from:[email protected]");
            telnet.sendCommand("rcpt to:[email protected]");
            telnet.sendCommand("quit");

            telnet.disconnect();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Here apart form the telnet connection response, for every other sendCommand I'm getting an empty response. Can some one point me what could be the issue.

My output is something like this

TelnetSample.readResponse()
220 mx.xxxxxx.com ESMTP o86si4086625pfi.217 - gsmtp
==========================================================
Helo hi
TelnetSample.read()
output empty
==========================================================
mail from:[email protected]
TelnetSample.read()
output empty
==========================================================
rcpt to:[email protected]
TelnetSample.read()
output empty
==========================================================
quit
TelnetSample.read()
output empty
==========================================================

Upvotes: 0

Views: 3607

Answers (2)

Vladislav Kysliy
Vladislav Kysliy

Reputation: 3736

This code has several issue:

  • the first issue is in readResponse method. When you use readLine() you can easy block your code and will wait forever. Please have a look at discussion How to determine the exact state of a BufferedReader?
  • the second you don't send any CR/LF chars. Server got your requests like a single line. Ex:

mail from:[email protected] to:[email protected]

To fix first issue you can choose several ways:

  • use multi-threading model
  • use NIO API. I would recommend Netty for that. Especially for your case as i can see you didn't use Telnet protocol at all, you connected to SMTP server.

Quick fix but the worst, wait first line from server and go on:

public String readResponse() {
    System.out.println("TelnetSmtpSample.readResponse()");
    StringBuilder out = new StringBuilder();
    try {
        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
        out.append(reader.readLine());
    } catch (Exception e) {
        e.printStackTrace();
    }

    System.out.println(out.toString());
    System.out.println("=====================");

    return out.toString();
}

To fix second one:

    telnet.sendCommand("Helo hi\r\n");
    telnet.sendCommand("mail from:[email protected]\r\n");
    telnet.sendCommand("rcpt to:[email protected]\r\n");
    telnet.sendCommand("quit\r\n");

Upvotes: 1

corinne
corinne

Reputation: 328

It's possible read2 is getting a null value back from the input stream before data is actually returned. Try something like this:

private String read2() {

    StringBuffer sb = new StringBuffer();

    try {
        do {
            if (in.available() > 0) {
                char ch = (char) in.read();
                sb.append(ch);
            } else {
                Thread.sleep(1000);
            }
        } while (in.available()>0);

        String output = new String(sb);
        return output;

    } catch (Exception e) {
        e.printStackTrace();
    }

    return null;

}

Upvotes: 0

Related Questions