views:

57

answers:

3

I work for a large organization that supports many different sites on a nation wide network. Our vendor supplies diagnostic tools for the hardware we use at each site. The diagnostics and reports are accessed via Telnet.

The problem is we want to monitor all sites simultaneously and currently we can only check them one at a time (via telnet).

I have already built something that will use Runtime.exec(String) to send ping commands to each IP address. But now I want to be able to send specific commands automatically using the vendor's diagnostic and reporting tools. Any ideas on the best way to do this? NOTE we have a hybrid system - some of the sites are behind a firewall some are not. A complete solution would be ideal but I will settle for a partial one as well.

Could it be as simple as getting the input and output streams of the Process object returned by the Runtime.exec(String) and send my commands to the input and reading the response on the output? Or should I be connecting to port 23 (the usual telnet port) and then behave as any other client-server system. Or something else completely different?

I am continuing to try things out, just brainstorming at this point...

CODE: (sensitive information removed)

void exec(String ip)
{
  Socket sock = null;
  BufferedReader br = null;
  PrintWriter pw = null;

  try
  {
    sock = new Socket(ip, 23);

    br = new BufferedReader(new InputStreamReader(sock.getInputStream()));
    pw = new PrintWriter(sock.getOutputStream());

    this.read(br);
    System.out.println("Sending username");
    pw.println("username");
    this.read(br);  // Always blocks here
    System.out.println("Sending password");
    pw.println("password");
    this.read(br);

    pw.close();
    br.close();
    sock.close();
  }
  catch(IOException e)
  {
    e.printStackTrace();
  }
}

void read(BufferedReader br) throws IOException
{
  char[] ca = new char[1024];
  int rc = br.read(ca);
  String s = new String(ca).trim();

  Arrays.fill(ca, (char)0);

  System.out.println("RC=" + rc + ":" + s);

//String s = br.readLine();
//      
//while(s != null)
//{
//  if(s.equalsIgnoreCase("username:"))
//    break;
//          
//  s = br.readLine();
//          
//  System.out.println(s);
//}
+4  A: 

Why don't you simply use the Socket system ?

Open a socket to the chosen server on port 23 and send your own commands from here.


Here is a quick example :

public class EchoClient {
    public static void main(String[] args) throws IOException {

        Socket pingSocket = null;
        PrintWriter out = null;
        BufferedReader in = null;

        try {
            pingSocket = new Socket("servername", 23);
            out = new PrintWriter(pingSocket.getOutputStream(), true);
            in = new BufferedReader(new InputStreamReader(pingSocket.getInputStream()));
        } catch (IOException e) {
            return;
        }

        out.println("ping");
        System.out.println(in.readLine());
        out.close();
        in.close();
        pingSocket.close();
    }
}

Resources :

Colin Hebert
+1 for the right approach
Erick Robertson
Tried but readLine() locks up. I put the readLine() inside a loop to read all the received lines but it locks up almost immediately. What I see is:
BigMac66
Damn return key! What I see is Vendor's name\n blank line \n username:\n And it freezes at that point. I know that readLine() blocks so I suspect it is waiting for an EOF to unblock but never gets one so I can never send my username etc. This is precisely the low level of detail I want to avoid. Sure I could look for username: and simply not read the next line but I want to avoid writing my own telnet app :)
BigMac66
One way or another you'll have to wait for the username to be asked before sending the username, so basically you'll still need to write your own "telnet app". But for your current problem you should use two threads, one for reading, and another one for sending answers at the right time.
Colin Hebert
I tried different variations of read - all lock up right after I send the username. The very next read blocks - I don't even get the password: prompt.
BigMac66
I'll post what I have...
BigMac66
Did you send a username **after** the server prompted "username:" ?
Colin Hebert
Yep. In one variant I even waited till I read the string "username:" - still blocks on the very next read...
BigMac66
Ha, found it. You forgot to flush data. Try `new PrintWriter(sock.getOutputStream(), true)` to enable autoflush, or you can call `flush()` manually after each `println()`
Colin Hebert
Awesome dude! Amazing how something so simple can make such big difference. It is still a little flaky but at least there is progress! Still don't want to have to implement code to process all the responses I am likely to get but this particular job pays by the hour :)
BigMac66
A: 

telnet is almost bare tcp. you can probably make a socket connection, write commands, read responses.

well - telnet does have some control commands that can be mixed with data stream. you can probably program to ignore them. or, to be perfectly protocol aware, use a java telnet client package.

irreputable
Can you suggest a telnet package - simple and small preferably.
BigMac66
A: 

Expect is a scripted (non-Java) possibility. It's an older tool, see the Pros and Cons at Wikipedia.

David Hunt