Delphi Indy Ping错误10040

时间:2012-10-04 08:18:05

标签: delphi ping indy10

我有一小段代码通过ping它来检查计算机是否处于活动状态。我们用的是一个有40台电脑的房间,我想通过我的程序远程查看哪个还活着。

因此我使用indy

写了一个小ping函数
function TMainForm.Ping(const AHost : string) : Boolean;
var
  MyIdIcmpClient : TIdIcmpClient;
begin
  Result := True;

  MyIdIcmpClient := TIdIcmpClient.Create(nil);
  MyIdIcmpClient.ReceiveTimeout := 200;
  MyIdIcmpClient.Host := AHost;

  try
    MyIdIcmpClient.Ping;
    Application.ProcessMessages;
  except
    Result := False;
    MyIdIcmpClient.Free;
    Exit;
  end;
  if MyIdIcmpClient.ReplyStatus.ReplyStatusType <> rsEcho Then result := False;

  MyIdIcmpClient.Free;
end;

所以我已经在家里开发了我的无线网络,并且工作正常。

当我重新开始工作时,我进行了测试,并收到错误消息

Socket Errod # 10040 Message too long

在工作中我们有固定的IP和所有计算机,我在同一个子网中。

我试图断开与固定IP的连接并连接到wifi,当然这是DHCP,而不是在同一个子网中,它只是工作正常。

我尝试在互联网上搜索此错误以及如何解决但未找到太多信息。

当然我试图将默认缓冲区大小更改为更大的值,但它没有改变任何东西我仍然在同一子网内的固定IP上得到错误。

此外,我不知道这是否有助于找到解决方案,但我的代码会处理异常,但在这种情况下,引发错误大约需要3-4秒,而Timeout设置为200毫秒。而且我不能等待每一次ping。

顺便说一句,我使用的是delphi 2010,我认为它是indy 10.我也在XE2上进行了测试但是同样的错误。

任何想法

-----编辑-----

这个问题已经回答了,现在我尝试在多线程中运行这个问题并且我已经提出了另一个问题 Delphi (XE2) Indy (10) Multithread Ping

3 个答案:

答案 0 :(得分:6)

PacketSize属性设置为24

function TMainForm.Ping(const AHost : string) : Boolean;
var
  MyIdIcmpClient : TIdIcmpClient;
begin
  Result := True;

  MyIdIcmpClient := TIdIcmpClient.Create(self);
  MyIdIcmpClient.ReceiveTimeout := 200;
  MyIdIcmpClient.Host := AHost;
  MyIdIcmpClient.PacketSize := 24;
  MyIdIcmpClient.Protocol := 1;
  MyIdIcmpClient.IPVersion := Id_IPv4;

  try
    MyIdIcmpClient.Ping;
    // Application.ProcessMessages; // There's no need to call this!
  except
    Result := False;
    Exit;
  end;
  if MyIdIcmpClient.ReplyStatus.ReplyStatusType <> rsEcho Then result := False;

  MyIdIcmpClient.Free;
end;

答案 1 :(得分:1)

对于XE5和Indy10,即使使用不同的数据包大小,这仍然是一个问题。

要回答更加隐秘的修复:

ABuffer := MyIdIcmpClient1.Host + StringOfChar(' ', 255);

这是一个“神奇”的解决方案,可以解决Indy10组件中存在错误的问题(如果我理解了Remy Lebeau的话)。

我的推测是,它与接收缓冲区的大小有一些联系。为了测试我的理论,我可以使用任何字符,根本不需要包含主机地址。仅使用接收缓冲区所需的字符数。我使用这个小代码(C ++ Builder XE5)非常成功地执行Ping(所有其他值都是默认值):

AnsiString Proxy = StringOfChar('X',IcmpClient->PacketSize);

IcmpClient->Host = Host_Edit->Text;
IcmpClient->Ping(Proxy);

如您所见,我创建了一个与PacketSize属性长度相同的字符串。你填的是无足轻重的。

这可能对@RemyLebeau在修复工作时有所帮助。

答案 2 :(得分:0)

使用此代码

  

ABuffer:= MyIdIcmpClient1.Host + StringOfChar('',255);

     

MyIdIcmpClient.Ping(ABuffer);