简体   繁体   English

使用commons-net的自动Telnet客户端

[英]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. 我的要求是使用Java程序通过telnet连接到某些服务器,并运行一些命令并读取响应。 Based on these responses I need to perform some operation 基于这些响应,我需要执行一些操作

I strated with https://stackoverflow.com/a/1213188/1025328 我用https://stackoverflow.com/a/1213188/1025328大步向前

I'm using commons-net and my program is something like this: 我正在使用commons-net,我的程序是这样的:

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:xyz@testmail.com");
            telnet.sendCommand("rcpt to:pk@testmail.com");
            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. 除了telnet连接响应以外,对于其他每一个sendCommand我都会得到一个空响应。 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:xyz@testmail.com
TelnetSample.read()
output empty
==========================================================
rcpt to:pk@testmail.com
TelnetSample.read()
output empty
==========================================================
quit
TelnetSample.read()
output empty
==========================================================

This code has several issue: 这段代码有几个问题:

  • the first issue is in readResponse method. 第一个问题是在readResponse方法中。 When you use readLine() you can easy block your code and will wait forever. 使用readLine()您可以轻松地阻塞代码,并将永远等待。 Please have a look at discussion How to determine the exact state of a BufferedReader? 请看一下讨论如何确定BufferedReader的确切状态?
  • the second you don't send any CR/LF chars. 第二,您不发送任何CR / LF字符。 Server got your requests like a single line. 服务器收到您的请求就像一行。 Ex: 例如:

mail from:xyz@testmail.comrcpt to:pk@testmail.comquit 邮件从:xyz@testmail.comrcpt到:pk@testmail.comquit

To fix first issue you can choose several ways: 要解决第一个问题,您可以选择几种方法:

  • use multi-threading model 使用多线程模型
  • use NIO API. 使用NIO API。 I would recommend Netty for that. 我为此建议Netty Especially for your case as i can see you didn't use Telnet protocol at all, you connected to SMTP server. 特别是对于您的情况,因为我可以看到您根本没有使用Telnet协议,因此您已连接到SMTP服务器。

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:xyz@testmail.com\r\n");
    telnet.sendCommand("rcpt to:pk@testmail.com\r\n");
    telnet.sendCommand("quit\r\n");

It's possible read2 is getting a null value back from the input stream before data is actually returned. 在实际返回数据之前,read2可能会从输入流中获取空值。 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;

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM