Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
TIdIPMCastClient problem
#1
IdIPMCastClient ( Delphi 7 and Rad studio Delphi 12.1, indy 9 and 10) not receive multicast message from unix/linux (from Windows 10 is Ok) computer.
Reply
#2
Can you be more specific? What does your code look like? Did you verify the multicast messages are reaching the computer and the specific NIC you are listening on? Can you receive the messages with any other multicast apps running on the same computer?

Reply
#3
I have a Windows 10 computer with 3 LAN card. WireShark show MultiCast data (dest IP - 239.....). This information arrives from afar, perhaps from a Linux computer. Next programs not receive data:
- D7 with INDY 9
- Rad Studio D 10.2 with Indy 10
- C# without Indy.
All program receive similar data (send from D or C#) between two computer with Windows 10.
Reply
#4
The fact that you have the same problem with C# means this is not an Indy issue. Either you are doing something fundamentally wrong in your handling of multicast, or your environment is just not setup correctly. Either way, you still haven't provided specific details to help you diagnose this. Again, what does your code look like? What does your NIC setup look like? What does the Wireshark capture look like? Details matter.

Reply
#5
Dear all,

after a long time searching and  reading, i'm quite confused.

I have written, a piece of test code, which can be compiled on Windows 32bits as well as 64bit Linux. Under Windows, the test code shows the incoming messages, under Ubuntu, there will be nothing received (even if it is proofed, that my real application can send out multicast messages (which then can be received by the test code under Windows !!).

so at the end, i have a similar problem, as KIPROV has it.

Can somebody explain me, what I'm doing wrong ? Thanks in advance for every hint.

George

Here is my receiving code :

Code:
// +-------------------------------------------------------------------------------------
program test;

// +-------------+---------+------+-------+-------------------------------------
// ¦ Date        ¦ Fam.Ver ¦ Main ¦ Minor ¦ Description
// +-------------+---------+------+-------+-------------------------------------
// ¦ 2024-11-11  ¦ 0000    ¦ 00  ¦ 00    ¦ First release
// +-------------+---------+------+-------+-------------------------------------

{$APPTYPE CONSOLE}

// ¦ Units for Linux:  Posix.Stdlib, Posix.SysStat, Posix.SysTypes, Posix.Unistd, Posix.Signal, Posix.Fcntl,

uses
  System.SysUtils,
  System.Types,
  System.IOUtils,
  System.Classes,
  System.RTLConsts,
  system.DateUtils,
  System.SyncObjs,
  IdSSLOpenSSL,
  idSSlOpenSSLHeaders,
  IdIPMCastClient,
  IdSockethandle,
  {$IFDEF linux}
  Posix.Stdlib, Posix.SysStat, Posix.SysTypes, Posix.Unistd, Posix.Signal, Posix.Fcntl,
  {$ENDIF }
  {$IFDEF MSWINDOWS}
  activex,
  {$ENDIF }
  IdGlobal;

const
  EXIT_FAILURE        = 1;
  EXIT_SUCCESS        = 0;

  coAppname            = 'ServerMCTest';
  coFamilyVer          = '0000';
  coAppMajorVer        = '0';
  coAppMinorVer        = '0';
  coAppVersion        = coFamilyVer+'.'+coAppMajorVer+'.'+coAppMinorVer;
  coApptitle          = coAppname+' - (c) 2024 Reference Data Lab GmbH';

// +--------------------------------------------------------------------------
// ¦ Type Definition for local Objects
// +--------------------------------------------------------------------------
type
  TRunC = class(TComponent)
  Private

  public
    { Public-Deklarationen }
    FBUSRX      : TIdIPMCastClient;
    Socket      : TIdSocketHandle;
    running    : Boolean;
    Procedure  DoBusRXProcessing(Sender: TObject; const AData: TIdBytes;  ABinding: TIdSocketHandle);
  end;

  // +--------------------------------------------------------------------------
// ¦ Globale Variablen
// +--------------------------------------------------------------------------
var
  runc : TRunC;

// +--------------------------------------------------------------------------
// ¦ Linux Signal handling
// +--------------------------------------------------------------------------
{$IFNDEF MSWINDOWS}
procedure HandleSignals(SigNum: Integer); cdecl;
// 1. If SIGTERM is received, shut down the daemon and exit cleanly.
// 2. If SIGHUP is received, reload the configuration files, if this applies.
begin
  case SigNum of
    SIGTERM:
    begin
      runc.running := False;
    end;
    SIGHUP:
    begin
      // Reload configuration
    end;
  end;
end;
{$ENDIF}

procedure TrunC.DoBusRXProcessing(Sender: TObject; const AData: TIdBytes;  ABinding: TIdSocketHandle);
Var
  RXBuffer : String;
begin
  {$IFDEF MSWINDOWS} coInitialize(nil);{$ENDIF }
  // ¦ Einrichten

  // ¦ Empfang der eingehenden XML Nachricht und überprüfung derselben
  RXBuffer:=utf8String(Trim(BytesToString(AData)));
  try
    writeln(RxBuffer);
  Except
  end;

  {$IFDEF MSWINDOWS} coUnInitialize;{$ENDIF }
end;

// +--------------------------------------------------------------------------
// ¦ Main Application
// +--------------------------------------------------------------------------
begin
  runc:=Trunc.Create(nil);


  writeln(coApptitle);
  writeln('Version : '+coAppVersion);
  writeln('STATUS  : DEVELOPMENT 3');

  // ¦ Einrichten FBUSRX
  runc.FBUSRX:=tIdIPMCastClient.Create(runc);
  runc.FBusRx.BufferSize:=1500;

  runc.FBusrX.ReuseSocket:=rsTrue;
  runc.Fbusrx.MulticastGroup:='224.0.0.1';
  runc.FBusRx.DefaultPort:=38001;
  runc.FBusRX.ReuseSocket:=rsTrue;
  runc.FBusRX.OnIPMCastRead:=runC.DoBusRxProcessing;
  runc.FBusRX.ThreadedEvent:=true;

  runc.FbusRX.Bindings.Clear;
  runc.Socket:=runc.FbusRX.Bindings.Add;

  runc.Socket.IP:='0.0.0.0';
  runc.Socket.Port:=38001;

  runc.FBusRX.active:=true;
  runc.running:=true;

  {$IFDEF MSWINDOWS}
  coinitialize(nil);
  {$ENDIF}

  // +------------------------------------------------------------------------
  // ¦ Mainloop Windows
  // +------------------------------------------------------------------------
  {$IFDEF MSWINDOWS}
  try
    while runc.Running=true do
      begin
        sleep(10000);
      end;
  except
    on E: Exception do
      begin
        Writeln(E.ClassName, ': ', E.Message);
        runc.running:=False;
        writeln('ERROR:'+E.ClassName+ ': '+ E.Message);
      end;
  end;
  {$ENDIF}
  // +------------------------------------------------------------------------

  // +------------------------------------------------------------------------
  // ¦ Mainloop Linux
  // +------------------------------------------------------------------------
  {$IFDEF LINUX}
  try
    while runc.Running=true do
      begin
        // deamon actual code
        sleep(10000);
      end;
    ExitCode := EXIT_SUCCESS;
  except
    on E: Exception do
      begin
        ExitCode := EXIT_FAILURE;
        runc.running:=false;
        writeln('ERROR:'+E.ClassName+ ': '+ E.Message);
      end;
  end;
  {$ENDIF}
  // +------------------------------------------------------------------------

  // +------------------------------------------------------------------------
  // ¦ Aufräumen
  // +------------------------------------------------------------------------
  {$IFDEF MSWINDOWS}coUninitialize;{$ENDIF}
  runc.Free;
end.
Reply
#6
(11-11-2024, 10:55 AM)swissdreamer Wrote: so at the end, i have a similar problem, as KIPROV has it.

The same questions I asked KIPROV earlier apply to your situation as well. And since KIPROV didn't answer them, we can't know if you have the exact same problem.

Can you provide more details about your setup?  Did you verify the multicast packets are arriving on the NIC you are binding to?

As for your code:

- Multicast handling on Nix platforms is slightly different than on Windows.  You maybe running into an issue similar to this one (which was not resolved at the time):

https://en.delphipraxis.net/topic/8838-t...ace-issue/

- Why you are involving ActiveX when there is no ActiveX/COM object being used anywhere?

- In DoBusRXProcessing(), your string handling is weird.  You are converting AData to UTF-16 via ASCII (Indy's default encoding), then converting the UTF-16 to UTF-8, just to convert it back to UTF-16.  You don't need the UTF8String cast at all.  If the bytes are UTF-8, then you should tell that to BytesToString(), eg:

Code:
RXBuffer := Trim(BytesToString(AData, IndyTextEncoding_UTF8));

Alternatively, you can skip BytesToString() and just use IIdTextEncoding.GetString() directly:

Code:
RXBuffer := Trim(IndyTextEncoding_UTF8.GetString(AData));

Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)