我尝试使用Indy 10.5.5(与Delphi 2010一起提供):
并且没有成功,此外,我完全不了解Indy内部的细面条逻辑,现在不知道为什么它不起作用或我应该如何将字符串发送到服务器并获取结果。需要一些示例代码来研究。
问题的形式:在哪里可以得到涵盖TIdTelnet组件的第三方贡献的演示? (indyproject.org演示网页没有一个)
Telnet的主要问题在于,它不像大多数其他Internet协议那样使用命令/响应模型。任何一方都可以随时发送数据,并且数据的每个方向都独立于另一个方向。 TIdTelnet
通过运行内部读取线程来接收数据这一事实得到了反映。因此,您不能像使用其他Indy组件那样简单地连接,发送命令并等待单个代码块中的响应。您必须编写命令,然后等待OnDataAvailable
事件触发,然后解析数据以确定其实际内容(并准备处理可能接收到部分数据的情况,因为这正是TCP /知识产权)。
[如果要连接到实际实现命令/响应模型的服务器,那么最好直接使用TIdTCPClient
而不是TIdTelnet
(然后,如果服务器确实使用Telnet,则手动实施任何Telnet序列解码,如今很少见,但并非没有)。对于Indy 11,我们可以重构TIdTelnet
的逻辑以支持非线程版本,但这尚未确定。
与印第完成。没有评论..只是旧代码:-)telnet不喜欢发送字符串kommand ..使用sendch。
telnetdude.Host := 1.1.1.1;
try
telnetdude.connect;
except
on E: Exception do begin
E.CleanupInstance;
end; {except}
if telnetdude.Connected then begin
for i := 1 to length(StringToSend) do telnetdude.sendch(StringToSend[i]);
telnetdude.sendch(#13);
end;
end; {while}
end; {if}
if telnetdude.Connected then telnetdude.Disconnect;
end;
我希望这可以帮助任何寻求类似问题答案的人。
首先,似乎是典型的命令/响应模型(如上所述,实际上并不适用)。
所以我只是让它适用于某些非常简单的应用程序(重新启动路由器)。
[以上来自Johnny Lanewood的代码的特定补充(可能需要澄清)a)您必须发送#13来确认命令b)我发送的每条命令都“挂起” /我请求直到启用ThreadedEvent的响应才挂起。 (这是我的大问题)
c)OnDataAvailable事件会告诉您何时可以从Telnet服务器获得新数据-但是不能保证这些数据是什么-即,您在命令行中获得的信息很漂亮/以前响应中附加的内容。但这不是命令的特定响应行-远程登录服务器返回的内容(可能是欢迎信息,ASCII绘图等)。
鉴于上面的(c),宁愿检查OnDataAvailable事件并解析数据(知道您的期望)。当输出停止时(即您需要为此建立机制),您可以解析数据并确定服务器是否准备好从客户端进行新的操作。出于下面我的代码的目的,我设置了一个读取超时,并且我只使用了Sleep(2000)-无知地期望没有错误,并且服务器在睡眠后可以为下一个命令准备就绪。我最大的绊脚石是ThreadedEvent:= True(请参见上面的b)
因此,我的工作解决方案(对于特定的应用程序,可能对某些人来说是可怕的。
lIDTelnet := TIdTelnet.Create(nil); try lIdTelnet.ReadTimeout := 30000; lIDTelnet.OnDataAvailable := TDummy.Response; lIDTelnet.OnStatus := TDummy.Status; lIdTelnet.ThreadedEvent := True; try lIDTelnet.Connect('192.168.0.1', 23); if not lIDTelnet.Connected then Raise Exception.Create('192.168.0.1 TELNET Connection Failed'); Sleep(2000); lIdtelnet.SendString(cst_user + #13); Sleep(2000); lIdtelnet.SendString(cst_pass + #13); Sleep(2000); lIdtelnet.SendString(cst_reboot + #13); Sleep(2000); if lIDTelnet.Connected then lIDTelnet.Disconnect; except //Do some handling end; finally FreeAndNil(lIdTelnet); end;
然后是>>
class procedure TDummy.Response(Sender: TIdTelnet; const Buffer: TIdBytes); begin Write(TDummy.ByteToString(Buffer)); end; class function TDummy.ByteToString( const aBytes: TIdBytes): String; var i : integer; begin result := ''; for i := 0 to Length(aBytes) -1 do begin result := result + Char(aBytes[i]); end; end;