views:

410

answers:

5

I am using Java on Windows XP and want to be able to send commands to another program such as telnet. I do not want to simply execute another program. I want to execute it, and then send it a sequence of commands once it's running. Here's my code of what I want to do, but it does not work: (If you uncomment and change the command to "cmd" it works as expected. Please help.) This is a simplified example. In production there will be many more commands sent, so please don't suggest calling "telnet localhost".

    try
    {
        Runtime rt = Runtime.getRuntime();

        String command = "telnet";
        //command = "cmd";
        Process pr = rt.exec(command);

        BufferedReader processOutput = new BufferedReader(new InputStreamReader(pr.getInputStream()));
        BufferedWriter processInput = new BufferedWriter(new OutputStreamWriter(pr.getOutputStream()));

        String commandToSend = "open localhost\n";
        //commandToSend = "dir\n" + "exit\n";

        processInput.write(commandToSend);
        processInput.flush();

        int lineCounter = 0;
        while(true)
        {
            String line = processOutput.readLine();
            if(line == null) break;
            System.out.println(++lineCounter + ": " + line);
        }

        processInput.close();
        processOutput.close();
        pr.waitFor();
    }
    catch(Exception x)
    {
        x.printStackTrace();
    }
+2  A: 

It's not directly an answer to your question, but...

Instead of using Runtime.exec() you should use a ProcessBuilder and redirect stderr to stdout (ProcessBuilder.redirectErrorStream(true)). Otherwise your process could block if it writes something to stderr (Windows doesn't like it when the output of a process isn't read).

tangens
This is pretty close to a "direct answer" - you can start the process and read output from `Process.getOutputStream()` and write commands to `Process.getInputStream()`
D.Shawley
I tried this, and I get the same problem. The output from telent is not read. Program executes without printing anything.
bradvido
+2  A: 

That looks OK, as it won't be producing that much output, but you should really read and write in separate threads so it doesn't fill up the buffer and block waiting you to read before you reach the next step.

So if it's reaching the point where you flush the command you send to it, find out whether the Windows telnet client supports receiving commands from standard input rather than a console by piping the text you're sending to its standard input to it in a command prompt.

For example, echo dir c:\ | cmd causes cmd to run, list the c: drive contents and exit, much the same behaviour as if you typed dir c:\ into the console. But echo open localhost | telnet causes telnet to clear the screen then exit, rather than behaving the same way as if you typed it into the console. As telnet needs to mask user input for passwords, it's quite likely that it's using the console API rather than reading from standard input. It's help doesn't list any command arguments to tell it to read from standard input, so maybe you need to use a telnet implementation which is better suited to scripting.

Pete Kirkham
I agree. This is a simplified example to show my problem, so i kept it single threaded.Can you please explain what you mean by standard input vs. console and piping the text?
bradvido
@bradvido Well, `echo open localhost | telnet` doesn't work but `echo dir c: | cmd` does, so I suspect strongly that Windows telnet client is using the console API to detect keypresses rather than reading its input stream.
Pete Kirkham
@Pete Kirkham I see this now. This is obviously the problem i'm running into. Do you have any idea how i can write to an application's console instead of the input stream?
bradvido
+2  A: 

If you want to control a telnet session programatically from Java, you might be able to use this Java telnet library... you can do the same things (open connections, send username/password, send commands and receive results) but without actually spawning a separate process.

psmears
The telent was simply for an example. I need this to be generic so i can execute any executable and write commands to it
bradvido
+1  A: 

You may take a look at the Telnet Ant task you can call it directly in your code with out having to use a build.xml file.

You can also take a look at the source code and see how they do it.

OscarRyz
A: 

This is a simplified example.

http://java.pakcarid.com/Cpp.aspx?sub=328&ff=2559&topid=38&sls=24

lois