telnet循环问题

efly888 2018-12-27 10:52:05
循环telnet登陆路由器地址列表,找到配置中的型号,更新到表中,但是dataavailable事件好像是整个循环结束后才触发,不能在发送后就触发,导致无法实现。大家看看有什么办法。

with adoquery1 do
begin
close;
sql.clear;
sql.add('select ip from ipb');
open;
first;
for i:=0 to adoquery1.recordcount-1 do
begin
s1:= fieldbyname('ip').asstring;
sendmessage(s1); //编写发送路由器用户密码和查看配置命令过程 ,我以为在这里就可以触发ondataavailable事件,
将结果写到c:\telnet.txt文件中

if fileexists('c:\telnet.txt') then
begin
findx(sender); //找到路由器型号
postx(sender); //更新到表中
try
deletefile('c:\telnet.txt');
except
memo1.Lines.Add('删除telnet.txt错误');
end;
end else
memo1.Lines.Add('文件不存在!'); }

next;
end;
end;


procedure TForm1.IdTelnet1DataAvailable(Sender: TIdTelnet;
const Buffer: String);
var
pmyfile:textfile;
begin
try
assignfile(pmyfile,'c:\telnet.txt');
if fileexists('c:\telnet.txt')=false then
rewrite(pmyfile)
else
append(pmyfile);
writeln(pmyfile,pchar(buffer));
finally
closefile(pmyfile);
end;
end;
...全文
773 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
efly888 2019-01-07
  • 打赏
  • 举报
回复
不会啊卡住了,指点指点 bulestorm
BlueStorm 2019-01-03
  • 打赏
  • 举报
回复
循环你自己加上去不会吗?
efly888 2019-01-02
  • 打赏
  • 举报
回复
要在循环中实现
efly888 2019-01-02
  • 打赏
  • 举报
回复
问题还停留在:
with adoquery1 do
begin
close;
sql.clear;
sql.add('select ip from ipb');
open;
first;
for i:=0 to adoquery1.recordcount-1 do
begin
s1:= fieldbyname('ip').asstring;
sendmsg(s1); //编写发送路由器用户密码和查看配置命令过程 ,我以为在这里就可以触发ondataavailable事件,将结果写到c:\telnet.txt文件中

这里好像应该写点东西,怎么调用IdTelnet1DataAvailable这个相应?

if fileexists('c:\telnet.txt') then
begin
findx(sender); //找到路由器型号
postx(sender); //更新到表中
try
deletefile('c:\telnet.txt');
except
memo1.Lines.Add('删除telnet.txt错误');
end;
end else
memo1.Lines.Add('文件不存在!'); }

next;
end;
end;
BlueStorm 2019-01-02
  • 打赏
  • 举报
回复
或: Str := PChar(Buf);
BlueStorm 2019-01-02
  • 打赏
  • 举报
回复
如果StrList.Text := TEncoding.ANSI.GetString(Buffer);这一句编译报错(delphi版本原因),可以改为: StrList.Text := PChar(@Buffer[0]);
BlueStorm 2019-01-02
  • 打赏
  • 举报
回复

unit Unit1;

interface

uses
  Windows,Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, IdTelnet, IdGlobal;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    procedure IdTelnetDataAvailable(Sender: TIdTelnet; const Buffer: TIdBytes);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    IdTelnet: TIdTelnet;
    StrList: TStringList;
    procedure SendString(S: String);
    procedure WaitForPrompt(Str: String);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  StrList := TStringList.Create;
  Button1.OnClick := Button1Click;

  IdTelnet := TIdTelnet.Create(Self);
  With IdTelnet do
  begin
    Host := '127.0.0.1';
    Port := 23;
    OnDataAvailable := IdTelnetDataAvailable;
    Connect;
  end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  StrList.Free;
end;

procedure TForm1.WaitForPrompt(Str: String);
begin
  While (Memo1.Lines.Count = 0) or (Memo1.Lines[Memo1.Lines.Count-1] <> Str) do
  begin
    Sleep(100);
    Application.ProcessMessages;
  end;
end;

procedure TForm1.SendString(S: String);
var
  I: Integer;
begin
  for I := 1 to Length(S) do IdTelnet.SendCh(S[I]);
  IdTelnet.SendCh(#13);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  WaitForPrompt('login:');
  SendString('admin');
  WaitForPrompt('password:');
  SendString('admin');
  WaitForPrompt('something:');
  SendString('dis ver');
end;

procedure TForm1.IdTelnetDataAvailable(Sender: TIdTelnet; const Buffer: TIdBytes);
var
  I, Count: Integer;
begin
  Count := Memo1.Lines.Count;
  StrList.Text := TEncoding.ANSI.GetString(Buffer);
  for I := 0 to StrList.Count-1 do
  begin
    if (I = 0) and (Count <> 0) then
      Memo1.Lines[Count-1] := Memo1.Lines[Count-1] + StrList[I]
    else
      Memo1.Lines.Add(StrList[I]);
  end;
end;

end.
efly888 2018-12-31
  • 打赏
  • 举报
回复
执行IdTelnet1DataAvailable(tidtelnet1,s1);只是把要连接的IP地址发给IdTelnet1DataAvailable,没用! s1:= fieldbyname('ip').asstring;

sendmsg(s1),会执行连接设备发送命令,onIdTelnet1DataAvailable会得到信息,但是现在问题是无法在循环中及时响应。

问题还停留在:
sendmsg(s1); //编写发送路由器用户密码和查看配置命令过程 ,我以为在这里就可以触发ondataavailable事件,将结果写到
c:\telnet.txt文件中

这里好像应该写点东西,怎么调用IdTelnet1DataAvailable这个呢?

if fileexists('c:\telnet.txt') then

附上sendmsg()方法
procedure TForm1.sendmsg(host: string);
var i :integer;
s :string;
begin
IDTelnet1.Host := trim(host);
IDTelnet1.port := 23;

if idtelnet1.Connected then
idtelnet1.Disconnect;
if idtelnet1.Connected=false then
IdTelnet1.Connect;
sleep(300);
s := 'admin';
for i := 1 to length(s) do
IdTelnet1.SendCh(s[i]);
IdTelnet1.SendCh(#13);
sleep(300);
s := 'admin';
for i := 1 to length(s) do
IdTelnet1.SendCh(s[i]);
IdTelnet1.SendCh(#13);
sleep(300);
s := 'dis ver';
for i := 1 to length(s) do
IdTelnet1.SendCh(s[i]);
IdTelnet1.SendCh(#13);
end;
BlueStorm 2018-12-29
  • 打赏
  • 举报
回复
示范程序:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
  Vcl.StdCtrls, IdTelnet, IdGlobal;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    ButtonUser: TButton;
    ButtonPassword: TButton;
    procedure IdTelnetDataAvailable(Sender: TIdTelnet; const Buffer: TIdBytes);
    procedure ButtonUserClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure ButtonPasswordClick(Sender: TObject);
  private
    IdTelnet: TIdTelnet;
    StrList: TStringList;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  StrList := TStringList.Create;

  ButtonUser.OnClick     := ButtonUserClick;
  ButtonPassword.OnClick := ButtonPasswordClick;

  IdTelnet := TIdTelnet.Create(Self);
  With IdTelnet do
  begin
    Host := '127.0.0.1';
    Port := 23;
    OnDataAvailable := IdTelnetDataAvailable;
    Connect;
  end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  StrList.Free;
end;

procedure TForm1.ButtonUserClick(Sender: TObject);
begin
  IdTelnet.SendString('MyUser' + #13#10);
end;

procedure TForm1.ButtonPasswordClick(Sender: TObject);
begin
  IdTelnet.SendString('MyPassword' + #13#10);
end;

procedure TForm1.IdTelnetDataAvailable(Sender: TIdTelnet; const Buffer: TIdBytes);
var
  I, Count: Integer;
begin
  Count := Memo1.Lines.Count;
  StrList.Text := TEncoding.ANSI.GetString(Buffer);
  for I := 0 to StrList.Count-1 do
  begin
    if (I = 0) and (Count <> 0) then
      Memo1.Lines[Count-1] := Memo1.Lines[Count-1] + StrList[I]
    else
      Memo1.Lines.Add(StrList[I]);
  end;
end;

end.

doloopcn 2018-12-28
  • 打赏
  • 举报
回复
原因可能是有SendMessage,却没有ReciveMessage吧

你想用SendMessage来触发一个OnDataAvailable
你应该在Application.OnMessage中截获你的MSG,然后,执行
procedure TForm1.IdTelnet1DataAvailable(Sender: TIdTelnet; const Buffer: String);

Application.OnMessage
OnMessage(var MSG: tagMSG; var Handled: Boolean);
doloopcn 2018-12-28
  • 打赏
  • 举报
回复
引用 3 楼 efly888 的回复:
sendmessage就是自己起的名字,冲突了就改个名字,叫sendmsg好了。应该怎么写呢?

with adoquery1 do
begin
close;
sql.clear;
sql.add('select ip from ipb');
open;
first;
for i:=0 to adoquery1.recordcount-1 do
begin
s1:= fieldbyname('ip').asstring;
sendmsg(s1); //编写发送路由器用户密码和查看配置命令过程 ,我以为在这里就可以触发ondataavailable事件,将结果写到
c:\telnet.txt文件中

这里好像应该写点东西,怎么调用IdTelnet1DataAvailable这个呢?

if fileexists('c:\telnet.txt') then
begin
findx(sender); //找到路由器型号
postx(sender); //更新到表中
try
deletefile('c:\telnet.txt');
except
memo1.Lines.Add('删除telnet.txt错误');
end;
end else
memo1.Lines.Add('文件不存在!'); }

next;
end;
end;


这只是执行一个过程:
IdTelnet1DataAvailable(s1);
这 样就可以 执行事件了
BlueStorm 2018-12-28
  • 打赏
  • 举报
回复
sendmessage是发送Windows的消息,跟telnet一点关系也没有。
efly888 2018-12-28
  • 打赏
  • 举报
回复
sendmessage就是自己起的名字,冲突了就改个名字,叫sendmsg好了。应该怎么写呢?

with adoquery1 do
begin
close;
sql.clear;
sql.add('select ip from ipb');
open;
first;
for i:=0 to adoquery1.recordcount-1 do
begin
s1:= fieldbyname('ip').asstring;
sendmsg(s1); //编写发送路由器用户密码和查看配置命令过程 ,我以为在这里就可以触发ondataavailable事件,将结果写到
c:\telnet.txt文件中

这里好像应该写点东西,怎么调用IdTelnet1DataAvailable这个呢?

if fileexists('c:\telnet.txt') then
begin
findx(sender); //找到路由器型号
postx(sender); //更新到表中
try
deletefile('c:\telnet.txt');
except
memo1.Lines.Add('删除telnet.txt错误');
end;
end else
memo1.Lines.Add('文件不存在!'); }

next;
end;
end;

1,593

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 网络通信/分布式开发
社区管理员
  • 网络通信/分布式开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧