Autor Beitrag
Jocke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 28

XP
D6 Pers
BeitragVerfasst: Do 16.08.07 09:41 
Hallo,

ich schreibe gerade an einem Programm, mit dem man mit einem PC ein Linux-Gerät per Telnet automatisch konfigurieren können soll, unter Verwendung der Telnet Komponente aus den Indys.
Auf dem Linux-Gerät sollen in der Telnet-Sitzung verschiedene Befehle ausgeführt werden, z.B. Wechseln in ein bestimmtes Verzeichnis, erstellen einer Script.sh mit dem Vi Editor, einfügen eines Textes in die Datei, Vi beenden, Datei verschieben , usw.

Bei der manuellen Eingabe über Telnet kein Problem.
Jetzt sollen die Telnet-Kommandos über das Programm gesendet werden, etwa so :
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
      Form1.IdTelnet1.Create(nil);
      Form1.IdTelnet1.Host:=Form1.Edit1.text;
      Form1.IdTelnet1.Connect;
      If Form1.IdTelnet1.Connected Then
      begin
        Form1.IdTelnet1.WriteLn('cd /home');
        Form1.IdTelnet1.WriteLn('vi script.sh');
        Form1.IdTelnet1.WriteLn('i');
        Form1.IdTelnet1.WriteLn('cd /test');
        Form1.IdTelnet1.WriteLn('tar xjf /prog/prog.tar.bz2');
        Form1.IdTelnet1.WriteLn('cd /etc');
        Form1.IdTelnet1.WriteLn('^[');
        Form1.IdTelnet1.WriteLn(':wq');
        ...
        ...
      end;
      ...
      ...


Mein Problem ist jetzt, dass die Kommandos vom Programm derart schnell gesendet werden, dass das Linux-Gerät mit dem Verarbeiten nicht hinterher kommt, d.h. ein Teil der Befehle ist schon gesendet, noch bevor sich die Telnet-Konsole meldet.
Ich bräuchte also irgend eine Verzögerung zwischen den einzelnen Befehlen, oder es gibt eine andere Möglichkeiten mit dem Absetzen eines Befehls solange zu warten, bis sich das Linux-Gerät entsprechend gemeldet hat.
Mit der Demo zum Indy TelnetClient komme ich nicht weiter, weil dort nur von einer interaktiven Telnet-Sitzung ausgegangen wird, d.h. die Befehle werden manuell abgesetzt.

Ich wäre froh, wenn mir hier jemand eine Denkanstoß geben könnte.
Vielen Dank

_________________
mfg
Jocke
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Do 16.08.07 10:36 
Moin!

Eine Möglichkeit wäre auf eine Antwort bzw. Ergebnisnachricht zu warten - du kannst ja auch aus der Telnetsitzung lesen - und dann erst den nächsten Befehl abzusetzen. Bei Kommandos, die keine Ausgabe erzeugen, setzt du ein echo -continue- oder so dahinter, dann hast du auch wieder eine. :idea:

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Jocke Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 28

XP
D6 Pers
BeitragVerfasst: Do 16.08.07 10:59 
Hallo Narses,
vielen Dank für Deine Antwort. (Übrigens hat mir auch dein Posting zu Netzwerkkomponente verfügbar sehr weitergeholfen).

user profile iconNarses hat folgendes geschrieben:

Eine Möglichkeit wäre auf eine Antwort bzw. Ergebnisnachricht zu warten - du kannst ja auch aus der Telnetsitzung lesen - und dann erst den nächsten Befehl abzusetzen.


Da habe ich auch schon dran gedacht, da ich die Antworten vom Linux-Gerät auf die Telnet-Befehle ja eigentlich kenne. Aber gerade hier stehe ich auf dem Schlauch. Komme ich hier mit idTelnet.ReadLn() weiter ? Oder wie kann ich die Antworten abfragen bzw. darauf warten.

_________________
mfg
Jocke
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Do 16.08.07 11:05 
Moin!

user profile iconJocke hat folgendes geschrieben:
vielen Dank für Deine Antwort. (Übrigens hat mir auch dein Posting zu Netzwerkkomponente verfügbar sehr weitergeholfen).

Bitte, gern geschehen. :)

user profile iconJocke hat folgendes geschrieben:
Aber gerade hier stehe ich auf dem Schlauch. Komme ich hier mit idTelnet.ReadLn() weiter ? Oder wie kann ich die Antworten abfragen bzw. darauf warten.

Der Telnet-Client hat doch das Ereignis OnDataAvailable()(zumindest in Indy9), damit hab ich das bisher immer gemacht. ;)

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Jocke Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 28

XP
D6 Pers
BeitragVerfasst: Do 16.08.07 12:23 
Das bringt mich auf eine Idee.
Ich verwende bereits das Ereignis OnDataAvailable(), um die Telnet-Sitzung in einem Memofeld anzuzeigen.

Wenn ich nun am Ende der OnDataAvailable-Prozedur ein Boolean-Variable bereit:=true setze und dann in meiner Telnet-Prozedur so etwas mache wie
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
Form1.IdTelnet1.WriteLn('Befehl');
repeat
until bereit=true;
bereit:=false;
Form1.IdTelnet1.WriteLn('nächster Befehl');
repeat
until bereit=true;
bereit:=false;
Form1.IdTelnet1.WriteLn('nächster Befehl');
...

könnte das funktionieren ?

_________________
mfg
Jocke
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Do 16.08.07 12:44 
Moin!

Ich würde das so nicht machen, das ist thread-style-programming in einer ereignisorientierten Anwendung... :? brrr! :| (so, wie´s da steht, geht´s nebenbei eh nicht, da das Ereignis nie eintreten würde). Zum Thema ereignisorientierte Programmierung: FAQ-Beitrag. :les: ;)

Du könntest sowas machen:
  • pack alle Befehle in eine TStringList("CmdList"), alle OK-Antworten in eine weitere ("RcList"), die Indices synchron halten
  • Zeiger (=Integer) in die Listen ("P") auf 0 setzen, Verbindung zur LinuxBox aufbauen
  • einen Messagehandler für eine eigene Nachricht ("CM_NextCommand") definieren
  • wenn die Verbindung steht, wirst du wohl irgend eine Antwort erhalten -> das 1. Mal OnDataAvailabletritt ein
  • im OnDataAvailableprüfst du, ob die Daten von der LinuxBox in RcList[P]stehen (=Antwort OK); wenn die Antwort NICHT OK ist, Abbruch :nixweiss: ist die Antwort OK, dann sich selbst CM_NextCommandposten und im Handler CmdList[P]senden, dann Pweiterzählen :arrow: im nächsten OnDataAvailablegeht´s dann wieder genau so
  • der eigene Messagehandler ist deshalb nötig, um aus dem OnDataAvailable-Handler rauszukommen, sonst gibt das möglicherweise problematische Effekte (besonders, wenn dir irgend jemand den "Tipp mit APM" geben sollte... :?)
  • auf diese Weise baust du eine Ereigniskette auf, die von dem OnDataAvailable-Ereignis gesteuert wird :idea:
  • pack noch einen DeadMan-Timer mit rein (wird beim Senden gestartet und im OnDataAvailable immer wieder zurückgesetzt), der nach 5 Minuten oder so Abbricht, weil nix mehr zurück kommt

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Jocke Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 28

XP
D6 Pers
BeitragVerfasst: Do 16.08.07 13:33 
Hallo Narses,

erst mal vielen Dank für deine wirklich ausführliche Hilfe.
Das muss ich mir alles mal genauer anschauen.

_________________
mfg
Jocke