Trimiterea de comenzi telnet și citirea răspunsului cu Java [closed] (Programare, Java)

BigMac66 a intrebat.

Lucrez pentru o organizație mare care susține multe site-uri diferite pe o rețea națională. Furnizorul nostru furnizează instrumente de diagnosticare pentru hardware-ul pe care îl folosim la fiecare site. Diagnosticele și rapoartele sunt accesate prin Telnet.

Problema este că dorim să monitorizăm toate site-uri simultan și în prezent le putem verifica doar pe rând (prin Telnet).

Am construit deja ceva care va utiliza Runtime.exec(String) pentru a trimite comenzi ping la fiecare adresă IP. Dar acum vreau să pot trimite automat comenzi specifice folosind instrumentele de diagnosticare și raportare ale furnizorului. Aveți vreo idee cu privire la cea mai bună modalitate de a face acest lucru? NOTĂ Avem un sistem hibrid – unele dintre site-uri sunt în spatele unui firewall, altele nu. O soluție completă ar fi ideală, dar mă voi mulțumi și cu una parțială.

Ar putea fi la fel de simplu ca obținerea fluxurilor de intrare și ieșire ale obiectului Process returnat de către Runtime.exec(String) și să trimit comenzile mele la intrare și să citesc răspunsul la ieșire? Sau ar trebui să mă conectez la portul 23 (portul telnet obișnuit) și apoi să mă comport ca orice alt sistem client-server. Sau altceva complet diferit?

Continui să încerc lucruri, doar brainstorming în acest moment…

COD: (informații sensibile eliminate)

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);
//}

5 răspunsuri
Colin Hebert

De ce nu folosiți pur și simplu sistemul Socket ?

Deschideți un socket către serverul ales pe portul 23 și trimiteți propriile comenzi de aici.


Iată un exemplu rapid :

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();
    }
}

Resurse :

Comentarii

  • Am încercat, dar readLine() se blochează. Am pus readLine() în interiorul unei bucle pentru a citi toate liniile primite, dar se blochează aproape imediat. Ceea ce văd este: –  > Por BigMac66.
  • A naibii cheie de întoarcere! Ceea ce văd este numele furnizorului
    linia goală
    numele de utilizator:
    Și se blochează în acel moment. Știu că readLine() se blochează, așa că bănuiesc că așteaptă un EOF pentru a se debloca, dar nu primește niciodată unul, așa că nu pot trimite niciodată numele meu de utilizator etc. Acesta este exact nivelul scăzut de detalii pe care vreau să-l evit. Sigur că aș putea să caut username: și pur și simplu să nu citesc următoarea linie, dar vreau să evit să scriu propria mea aplicație telnet 🙂 –  > Por BigMac66.
  • Într-un fel sau altul va trebui să aștepți să ți se ceară numele de utilizator înainte de a trimite numele de utilizator, așa că, practic, tot va trebui să îți scrii propria „aplicație telnet”. Dar pentru problema ta actuală ar trebui să folosești două fire de execuție, unul pentru citire și altul pentru a trimite răspunsurile la momentul potrivit. –  > Por Colin Hebert.
  • Am încercat diferite variante de citire – toate se blochează imediat după ce trimit numele de utilizator. Următoarea citire se blochează – nici măcar nu primesc parola: prompt. –  > Por BigMac66.
  • Ha, am găsit-o. Ați uitat să spălați datele. Încearcă new PrintWriter(sock.getOutputStream(), true) să activați autoflush, sau puteți apela flush() manual după fiecare println() –  > Por Colin Hebert.
Dale

Problema când o faci la nivel de socket este că dintr-o dată trebuie să fii expert în protocoale, când tot ce vrei să faci sunt câteva comenzi telnet.

Am scris un driver deasupra de.mud.jta, dar lasă fire deschise și nu știu unde și cum să le rezolv. Mi se pare că trebuie să existe ceva mai bun decât să codificăm la nivel de protocol sau chestia asta veche JTA.

irefutabil

telnet este aproape tcp gol. probabil că poți face o conexiune socket, scrie comenzi, citește răspunsuri.

ei bine – telnet are unele comenzi de control care pot fi amestecate cu fluxul de date. probabil că puteți programa să le ignorați. sau, pentru a fi perfect conștient de protocol, utilizați un pachet client telnet java.

Comentarii

  • Puteți sugera un pachet telnet – de preferință simplu și mic. –  > Por BigMac66.
David Hunt

Așteptați-vă la este o posibilitate scriptată (non-Java). Este un instrument mai vechi, consultați Pro și Contra la Wikipedia.

Serak Shiferaw

Încercați să verificați Netty Java Library. au un set bun de Telnet , SSH și alte biblioteci de rețea foarte utile

https://netty.io

Tags: