简体   繁体   English

Delphi Indy Ping错误10040

[英]Delphi Indy Ping Error 10040

I have a small piece of code that checks if a computer is alive by pinging it. 我有一小段代码通过ping它来检查计算机是否处于活动状态。 We use to have a room with 40 computer and I wanna check remotely through my program which on is alive. 我们用一个有40台电脑的房间,我想通过我的程序远程检查哪个还活着。

Therefore I wrote a little ping function using indy 因此我用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;

So I've developped that at home on my wifi network and everthing just work fine. 所以我已经在家里开发了我的wifi网络,并且工作正常。

When I get back to work I tested and I get an error saying 当我重新开始工作时,我进行了测试,并且收到错误消息

Socket Errod # 10040 Message too long

At work we have fixed IPs and all the computer and I are in the same subnet. 在工作中我们有固定的IP和所有的计算机,我在同一个子网中。

I tried to disconnect from the fixed IP and connect to the wifi which of course is DHCP and not in the same subnet, and it is just working fine. 我试图断开与固定IP的连接并连接到wifi当然是DHCP而不是在同一个子网中,它只是工作正常。

I have tried searching the internet for this error and how to solve it but didn't find much info. 我试过在互联网上搜索此错误以及如何解决它但没有找到太多信息。

Of course I have tried to change the default buffer size to a larger value but it didn't change anything I still get the error on the fixed IP within same subnet. 当然我已经尝试将默认缓冲区大小更改为更大的值,但它没有改变任何东西我仍然在同一子网内的固定IP上得到错误。

Moreover, I don't know if this can help finding a solution, but my code treats exceptions, but in that case it takes about 3-4 seconds to raise the error whereas the Timeout is set to 200 milliseconds. 此外,我不知道这是否有助于找到解决方案,但我的代码处理异常,但在这种情况下,提高错误大约需要3-4秒,而Timeout设置为200毫秒。 And I cannot wait that long over each ping. 而且我不能等待每一次ping。

By the way I use delphi 2010 and I think it is indy 10. I also have tested on XE2 but same error. 顺便说一句,我使用delphi 2010,我认为它是indy 10.我也测试了XE2但是同样的错误。

Any idea 任何的想法

----- EDIT ----- -----编辑-----

This question is answered, now I try to have this running in multithread and I have asked another question for that Delphi (XE2) Indy (10) Multithread Ping 这个问题得到了解答,现在我尝试在多线程中运行这个问题,我又问了另一个问题: Delphi(XE2)Indy(10)Multithread Ping

Set the PacketSize property to 24 : 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;

For XE5 and Indy10 this is still a problem, even with different Packet Size. 对于XE5和Indy10,即使使用不同的数据包大小,这仍然是一个问题。

To answer the more cryptical fix: 要回答更加密码的修复:

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

This is a "magic" fix to get around the fact that there is a bug in the Indy10 component (if I have understood Remy Lebeau right). 这是一个“神奇”的解决方案,可以解决Indy10组件中存在错误的事实(如果我已经了解了Remy Lebeau的话)。

My speculation is that this has some connection with the size of the receive buffer. 我的推测是,它与接收缓冲区的大小有一些联系。 To test my theory I can use any character and don't need to include the host address at all. 为了测试我的理论,我可以使用任何字符,根本不需要包含主机地址。 Only use as many character you need for the receive buffer. 仅使用接收缓冲区所需的字符数。 I use this small code (C++ Builder XE5) to do a Ping with great success (all other values at their defaults): 我使用这个小代码(C ++ Builder XE5)非常成功地执行Ping(所有其他值都是默认值):

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

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

As you can see I create a string of the same length as the PacketSize property. 如您所见,我创建了一个与PacketSize属性长度相同的字符串。 What you fill it with is insignificant. 你填的是微不足道的。

Maybe this can be of help to @RemyLebeau when he work on the fix. 也许这可以帮助@RemyLebeau解决问题。

use this code 使用此代码

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

MyIdIcmpClient.Ping(ABuffer); MyIdIcmpClient.Ping(ABuffer);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM