These are chat archives for IndySockets/Indy

5th
Jun 2017
Remy Lebeau
@rlebeau
Jun 05 2017 03:37
@DelphiWorlds how are you sending the broadcast? What does that code look like?
DelphiWorlds
@DelphiWorlds
Jun 05 2017 04:43
Francesco Marano may have given me a solution in the forums.. the thread starts here:
https://forums.embarcadero.com/message.jspa?messageID=887844&tstart=0
I neglected to consider that the IPMCast classes have their own IPVersion property, as well as MulticastGroup property.. doh
DelphiWorlds
@DelphiWorlds
Jun 05 2017 09:28
if you read Francesco's last reply, his example code works on Windows, fails on iOS.. same error
It fails when setting the client active
DelphiWorlds
@DelphiWorlds
Jun 05 2017 11:18
TIdStackVCLPosix.GetLocalAddressList fails to retrieve any addresses for me on my Android 7 device, so I've created this Gist, in case it's of any use:
https://gist.github.com/DelphiWorlds/0733b6611707c8d5725ee42fd1ae01fd
Remy Lebeau
@rlebeau
Jun 05 2017 17:02
@DelphiWorlds TIdStackVCLPosix.GetLocalAddressList() being broken on Android is a known issue. There are comments to that effect in the code. I stay away from using Embarcadero's JNI Bridge interfaces because 1) they are not portable (they only work in Delphi, not in FreePascal), and 2) there are threading issues related to accessing Java objects in native code, so I try to stick with native solutions. Which I have not implemented for Android yet.
DelphiWorlds
@DelphiWorlds
Jun 05 2017 20:03
ok.. no clues about what might be causing the failure on iOS? I'm also having problems attempting to broadcast on each IP address.. for some reason or another using a loop it broadcasts only on the last address
procedure TForm1.SendBroadcast(const AServer: TIdIPMCastServer; const ABroadcast: string);
var
  I: Integer;
begin
  for I := 0 to FLocalAddresses.Count - 1 do
  begin
    if FLocalAddresses[I].IPVersion = AServer.IPVersion then
    begin
      AServer.Active := False;
      AServer.BoundIP := FLocalAddresses[I].IPAddress;
      AServer.BoundPort := AServer.Port;
      AServer.Active := True;
      AServer.Send(ABroadcast);
    end;
  end;
end;
Remy Lebeau
@rlebeau
Jun 05 2017 20:40
@DelphiWorlds I'm not a multicast expert, or an iOS user, I can't tell you why it fails on iOS. What is the actual error? On which line of code? Where are you setting AServer.MulticastGroup? Is that group valid on all networks you are trying to bind to?
DelphiWorlds
@DelphiWorlds
Jun 05 2017 20:43
I posted the error earlier, and it occurs when attempting to set Active to True on the TIdIPMCastClient
Remy Lebeau
@rlebeau
Jun 05 2017 20:43
@DelphiWorlds the code above is server, not client. Do you have problems if you use a separate TIdIPMCastServer for each local IP, instead of binding and re-binding a single TIdIPMcastServer over and over?
DelphiWorlds
@DelphiWorlds
Jun 05 2017 20:44
I mean earlier than that
For now I'll assume it's because the MulticastGroup value is invalid.. I'm far from a multicast expert, too ;-)
Remy Lebeau
@rlebeau
Jun 05 2017 20:48
@DelphiWorlds What is the EXACT error? What does the EXACT call stack look like when the error is raised?
DelphiWorlds
@DelphiWorlds
Jun 05 2017 20:50
I posted the exact error message earlier.. one moment and I'll have a call stack
Exact error message again:
Project dyld_sim raised exception class EIdSocketError with message 'Socket Error # 49
Cannot assign requested address.'.
Call stack:
System._DbgExcNotify(0,$C9B3010,$909364 {'EIdSocketError'},$6306C8,nil)
System.NotifyReRaise
:00017cc7 NotifyReRaise + $13
IdStack.TIdStack.RaiseSocketError(49)
IdStack.TIdStack.RaiseLastSocketError
IdStack.TIdStack.CheckForSocketError(-1)
IdStackVCLPosix.TIdStackVCLPosix.SetSocketOption(9,41,12,(no value),20)
IdStackBSDBase.TIdStackBSDBase.MembershipSockOpt(9,???,'0:0:0:0:0:0:0:0',12,Id_IPv6)
IdStackBSDBase.TIdStackBSDBase.AddMulticastMembership(9,'FF01:0:0:0:0:0:0:1','0:0:0:0:0:0:0:0',Id_IPv6)
IdSocketHandle.TIdSocketHandle.AddMulticastMembership('FF01:0:0:0:0:0:0:1')
:00633c46 TIdSocketHandle.AddMulticastMembership + $3A
IdIPMCastBase.TIdIPMCastBase.SetActive(True)
Multicast.TMulticastModule.EnableServices(True)
Multicast.TMulticastModule.Create($D820800)
the same code works on Windows.. but I'm guessing that may be irrelevant given differences in OS
Remy Lebeau
@rlebeau
Jun 05 2017 21:54
@DelphiWorlds The error is coming from setsockopt() when adding a local IP to the multicast group, which is done after the socket is bound locally. The local IP that is being passed in is 0:0:0:0:0:0:0 (aka in6addr_any), which comes from the TIdSocketHandle.IP property, which is updated after binding. If the socket is bound to a specific local IP and not to in6addr_any, the TIdSocketHandle.IP property should not be all zeros. That implies a possible failure in TIdSocketHandle.UpdateBindingLocal(). But no matter, because the local IP is not currently being passed to setsockopt(IPV6_ADD_MEMBERSHIP) in IPv6, it is set to the default multicast interface instead. Maybe that is what iOS is complaining about.