TIdIPMCastClient problem - kiprov - 07-10-2024
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.
RE: TIdIPMCastClient problem - rlebeau - 07-10-2024
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?
RE: TIdIPMCastClient problem - kiprov - 07-10-2024
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.
RE: TIdIPMCastClient problem - rlebeau - 07-10-2024
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.
RE: TIdIPMCastClient problem - swissdreamer - 11-11-2024
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.
RE: TIdIPMCastClient problem - rlebeau - 11-11-2024
(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-tidipmcastclient-group-join-on-second-interface-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));
|