Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 需要使用TIdTelnet与telnet服务器交互的示例/演示_Delphi_Telnet_Indy - Fatal编程技术网

Delphi 需要使用TIdTelnet与telnet服务器交互的示例/演示

Delphi 需要使用TIdTelnet与telnet服务器交互的示例/演示,delphi,telnet,indy,Delphi,Telnet,Indy,我曾尝试使用Indy 10.5.5(与Delphi 2010一起提供),用于: 连接到telnet服务器 执行用户名/密码身份验证(获得对命令shell的访问权) 执行命令并将结果数据返回给应用程序 而且没有成功,另外,我完全迷失在Indy内部的意大利面条逻辑中,现在不知道它为什么不起作用,也不知道我应该如何向服务器发送字符串并获取结果。需要一些示例代码来学习 问题的正式形式:我在哪里可以获得第三方提供的关于TIdTelnet组件的演示?(indyproject.org演示网页没有)Tel

我曾尝试使用Indy 10.5.5(与Delphi 2010一起提供),用于:

  • 连接到telnet服务器
  • 执行用户名/密码身份验证(获得对命令shell的访问权)
  • 执行命令并将结果数据返回给应用程序
而且没有成功,另外,我完全迷失在Indy内部的意大利面条逻辑中,现在不知道它为什么不起作用,也不知道我应该如何向服务器发送字符串并获取结果。需要一些示例代码来学习



问题的正式形式:我在哪里可以获得第三方提供的关于TIdTelnet组件的演示?(indyproject.org演示网页没有)

Telnet的主要问题是它不像大多数其他互联网协议那样使用命令/响应模型。任何一方都可以随时发送数据,数据的每个方向都与另一个方向无关。这反映在
TIdTelnet
中,它运行一个内部读取线程来接收数据。因此,您不能像使用其他Indy组件那样,在单个代码块中简单地连接、发送命令并等待响应。您必须编写命令,然后等待触发
OnDataAvailable
事件,然后解析数据以确定它实际上是什么(并准备好处理可能接收到部分数据的情况,因为这正是TCP/IP的工作方式)

如果您连接到实际实现命令/响应模型的服务器,那么最好直接使用
TIdTCPClient
而不是
TIdTelnet
(如果服务器真的在使用Telnet,则手动实现任何Telnet序列解码,这在当今很少见,但并非不可能)。对于Indy 11,我们可能会重构TIdTelnet的逻辑以支持非线程版本,但这一点尚未确定。 没有评论。。只是som旧代码:-) 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服务器获得新数据-但是不能保证这些数据是什么-也就是说,它与您在命令行中得到的数据/以前的响应中附加的数据相当。但它不是对您的命令的特定响应行-它是telnet服务器返回的任何内容(可能是欢迎信息、ASCII图形等)

考虑到上面的(c),我们更愿意检查OnDataAvailable事件并解析数据(知道您期望的是什么)。当输出停止时(即,您需要为此构建一个机制),您可以解析数据并确定服务器是否准备好从客户端接收新的内容。出于下面代码的目的,我设置了一个read timemout,并且只使用了Sleep(2000)——无意中希望没有错误,并且服务器将在睡眠后为下一个命令做好准备。 我最大的绊脚石是ThreadedEvent:=True(见上面的b)

因此,我的工作解决方案(针对特定应用,可能对某些人来说很可怕)

然后

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;

不,这不是禁忌。张贴你的实际问题,而不是仅仅要求一个工作的例子。你试过谷歌吗?很多其他问题都是通过参考文档来回答的。为什么每个人都试图关闭一个关于如何做某事的示例应用程序的问题。好吧,有两种可能的情况(a)有一个示例应用程序可用-在这种情况下,有链接的答案是可能的,但谷歌会做得更好,所以这里(b)没有这样的示例,在这种情况下,问题是广泛的。“但没有成功”的说法需要进一步解释。我可以看到其他观点。而不是要求演示。询问“使用TidTelent我如何连接到服务器、发送命令和接收响应?”避免使用“意大利面条逻辑”之类的评论,两分钟后谷歌发现这可能会有所帮助。嘿@RemyLebeau.:-)我想知道,您是否决定添加对TIdTelnet非线程版本的支持?但我想不会,因为现在是2018年,在我目前的版本(10.1)中,我仍然看不到任何可能性。我想要的(而不是完全替代的TIdTelnet版本)是使用非线程命令响应函数的额外可能性。我经常同时需要这两个选项(服务器发送状态msgs+我需要对某些命令的响应)。我认为基于TIdTCPClient从我自己开始写所有东西会困难得多…:-/@StanE Indy 11不是我最初想象的那样。这将是一个维护版本,用于放弃对旧编译器的支持,并清理当前代码(我应该为此写一篇博客)。更大的变化(新课程、重新设计等)被推回到印地12号。但是目前还没有计划使用非线程的
TIdTelnet
。在命令响应协议的中间支持非请求状态消息总是棘手的,它需要是协议设计本身的一部分。这不是Indy可以提供的通用包装器,因为它是非常特定于协议的。这是为什么?我真的不明白这个代码与这个问题有什么关系。它基本上与SendString()函数的作用相同。而且它不可能检索任何响应(特别是对某个命令的响应)。还是我想念som
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;