Delphi Indy Ping Error 10040

HpTerm picture HpTerm · Oct 4, 2012 · Viewed 14.5k times · Source

I have a small piece of code that checks if a computer is alive by pinging it. We use to have a room with 40 computer and I wanna check remotely through my program which on is alive.

Therefore I wrote a little ping function using indy

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.

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.

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.

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.

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. And I cannot wait that long over each ping.

By the way I use delphi 2010 and I think it is indy 10. I also have tested on XE2 but same error.

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

Answer

LaKraven picture LaKraven · Oct 4, 2012

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