Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Dec 11 10:55
    TommySlokky commented #274
  • Dec 11 10:54
    TommySlokky commented #274
  • Dec 11 10:54
    TommySlokky commented #274
  • Dec 11 10:53
    TommySlokky commented #274
  • Dec 11 10:53
    TommySlokky commented #274
  • Dec 11 00:36

    rlebeau on master

    Minor tweak to last pull reques… (compare)

  • Dec 11 00:29

    rlebeau on master

    fix compiling issues for IdStac… Merge pull request #273 from Bi… (compare)

  • Dec 11 00:29
    rlebeau closed #273
  • Dec 11 00:27
    rlebeau commented #275
  • Dec 11 00:26

    rlebeau on master

    Defining HAS_PRawByteString for… (compare)

  • Dec 11 00:19

    rlebeau on master

    Define PRawByteString for older… Merge pull request #275 from Bi… (compare)

  • Dec 11 00:19
    rlebeau closed #275
  • Dec 10 22:05
    Bi0T1N commented #274
  • Dec 10 21:36
    Bi0T1N commented #275
  • Dec 10 21:31
    Bi0T1N synchronize #275
  • Dec 10 19:25
    rlebeau commented #275
  • Dec 10 19:21
    rlebeau commented #275
  • Dec 10 14:50
    TommySlokky commented #274
  • Dec 10 14:39
    TommySlokky commented #274
  • Dec 10 14:37
    TommySlokky commented #274
elekgeek
@elekgeek
and BTW
procedure TForm2.Log(const s: string);
begin
  mLog.Lines.Add(s);
end;
elekgeek
@elekgeek
@rlebeau Just set Active to false, it already disconnects the clients for you apparently it is not shutting down any threads.. my code is very simple and you have already seen it..
Remy Lebeau
@rlebeau

@elekgeek your Log() function is directly accessing a UI component (a TMemo?). THAT IS NOT THREAD-SAFE! That could easily cause deadlocks (amongst many other problems). OnExecute is fired in a worker thread, so Log() MUST synchronize with the main UI thread. I suggest it use TThread.Queue() or TIdNotify for that purpose (depending on your version of Delphi). That would avoid any cross-thread access issues, avoid any deadlock scenarios, and avoid blocking the OnExecute code (which should not need to wait on the UI to display log messages). For example:

procedure TForm2.Log(const s: string);
begin
  TThread.Queue(nil,
    procedure
    begin
      mLog.Lines.Add(s);
    end
  );
end;

or:

uses
  ..., IdSync;

type
  TLog = class(TIdNotify)
  protected
    FMsg: string;
    procedure DoNotify; override;
  public
    constructor Create(const s: string); reintroduce;
  end;

constructor TLog.Create(const s: string);
begin
  inherited Create;
  FMsg := s;
end;

procedure TLog.DoNotify;
begin
  Form2.mLog.Lines.Add(FMsg);
end;

procedure TForm2.Log(const s: string);
begin
  TLog.Create(s).Notify;
end;
Justin
@klsyzzz
hi there, just wondering is there an example for using TIdHTTP and NTLM Authentication in delphi?
elekgeek
@elekgeek

@rlebeau fabulous, both work like a charm

thanks a lot

Justin
@klsyzzz
I need to call a httpPost action from within Delphi and using NTLM auth
Remy Lebeau
@rlebeau
@klsyzzz NTLM support in Indy is spotty at best. There are two different NTLM classes available for TIdHTTP - TIdNTLMAuthentication in IdAuthenticationNTLM.pas (portable but untested), and TIdSSPINTLMAuthentication in IdAuthenticationSSPI.pas (Windows only). In theory, you should be able to just add one of those units to your uses clause and let TIdHTTP handle the rest. In practice, .... umm, good luck? They either work or they don't. I have no way of testing either one, as I have no access to any HTTP servers that use NTLM
Justin
@klsyzzz
thank you @rlebeau , I will have a try and let you know how it goes
Justin
@klsyzzz
hi @rlebeau , I added IdAuthenticationNTLM.pas to my uses clause, and created an instance of TidHTTP, what I need to do next to enable NTLM auth? I didn't find any property on TidHTTP to select auth type, do I need to do the following:
auth := TIdNTLMAuthentication.Create;
IdHTTP1.AuthenticationManager.AddAuthentication(auth);
Remy Lebeau
@rlebeau
@klsyzzz just add the unit to the uses clause to register the class with TIdHTTP. TIdHTTP should then automatically use the class on any server that supports NTLM (though you can use the TIdHTTP.OnSelectAuthorization event to make sure that is what TIdHTTP picks, if multiple authentications are supported and registered). Now put your NTLM credentials in the TIdHTTP.Request.UserName and TIdHTTP.Request.Password properties, and assign a TIdHTTP.OnAuthorization event handler to promt the user for new credentials if the initial credentials don't work
Justin
@klsyzzz
thanks @rlebeau, having issues getting it work, will ask you further questions once I'm more clear with it.
DelphiWorlds
@DelphiWorlds
I'm back on the Multicast issue - it seems I just need to find a multicast group that works. The information available is pretty confusing, as is iOS's apparent refusal to accept what I thought are valid groups. Any ideas on how to find something definitive?
I'm using a TIdIPMCastClient, and the following code:
procedure TForm1.FormCreate(Sender: TObject);
var
  I: Integer;
begin
  BroadcastListenerIPv6.DefaultPort := 6000;
  for I := 0 to BroadcastListenerIPv6.Bindings.Count - 1 do
    BroadcastListenerIPv6.Bindings.Items[I].Port := BroadcastListenerIPv6.DefaultPort;
  BroadcastListenerIPv6.MulticastGroup := 'FF02:0:0:0:0:0:0:1';
  BroadcastListenerIPv6.Active := True;
end;
Remy Lebeau
@rlebeau
@DelphiWorlds Obviously, you have to use whatever group IP is actually running on your local network. Is there an actual multicast group FF02:0:0:0:0:0:0:1 on your network?
DelphiWorlds
@DelphiWorlds
That's my point.. how do I know if there is one? Do I actually need to create it, and how?
Remy Lebeau
@rlebeau
@DelphiWorlds of course you need to have something setup on the network that will be sending packets to the group, and you need to know what that group is ahead of time. What else are you going to listen for packets from? TIdIPMCastClient joins a group. Anyone can send packets to the same group, and they will be delivered to whoever is joined
DelphiWorlds
@DelphiWorlds
procedure TForm1.FormCreate(Sender: TObject);
var
  I: Integer;
begin
  BroadcastServerIPv6.Port := 6000;
  BroadcastServerIPv6.MulticastGroup := 'FF02:0:0:0:0:0:0:1';
  BroadcastServerIPv6.Active := True;

  BroadcastListenerIPv6.DefaultPort := 6000;
  for I := 0 to BroadcastListenerIPv6.Bindings.Count - 1 do
    BroadcastListenerIPv6.Bindings.Items[I].Port := BroadcastListenerIPv6.DefaultPort;
  BroadcastListenerIPv6.MulticastGroup := 'FF02:0:0:0:0:0:0:1';
  BroadcastListenerIPv6.Active := True;
end;
Still does not work
Same error, i.e. 49 (Address invalid)
Remy Lebeau
@rlebeau
@DelphiWorlds well, you didn't say that earlier. That is an OS error, not an Indy error. Where exactly are you seeing that error? What local IP(s) are you binding the client to? You are only setting TIdSocketHandle.Port in code, are you leaving TIdSocketHandle.IP blank? I don't know if you can do that when joining a multicast group as a client
DelphiWorlds
@DelphiWorlds
when setsockopt is called.. that returns -1, and WSGetLastError returns 49
the client binds to a zero address (apparently meaning all)
Remy Lebeau
@rlebeau
@DelphiWorlds when calling setsockopt() with IPV6_ADD_MEMBERSHIP? It binds to interface index 0 (not address 0), which means use the default multicast interface.
DelphiWorlds
@DelphiWorlds
when calling setsockopt() with IPV6_ADD_MEMBERSHIP it passes the group, not an IP address
Remy Lebeau
@rlebeau
@DelphiWorlds IPV6_ADD_MEMBERSHIP specifies the group to join and the network interface to join with
DelphiWorlds
@DelphiWorlds
it's when it calls setsockopt() with IPV6_ADD_MEMBERSHIP that it fails
yes, I have worked that out
the interface index being used is 0, which coincides with other examples I've seen in my searching
Remy Lebeau
@rlebeau
@DelphiWorlds like I said, that just tells the OS to use the default multicast interface, whatever it happens to be, instead of having to specify a specific interface. You could always try stepping into the code with the debugger and play around with the indexes. But I think the first thing you should try is setting the TIdSocketHandle.IP property to the device's local IP when setting up the Bindings collection so TIdIPMCastClient has something specific to bind to locally before joining the group.
DelphiWorlds
@DelphiWorlds
I'm away from my Mac, so I'll check tonight (in about 8 hours from now).. thanks
DelphiWorlds
@DelphiWorlds
I've modified the code to set the only Binding to the first IPv6 address:
procedure TForm1.FormCreate(Sender: TObject);
var
  I: Integer;
  LIP: string;
begin
  FLocalAddresses := TIdStackLocalAddressList.Create;
  GStack.GetLocalAddressList(FLocalAddresses);

  for I := 0 to FLocalAddresses.Count - 1 do
  begin
    if FLocalAddresses[I].IPVersion = TIdIPVersion.Id_IPv6 then
    begin
      LIP := FLocalAddresses[I].IPAddress;
      Break;
    end;
  end;

  if LIP.IsEmpty then
    Exit; // <======

  BroadcastServerIPv6.Port := 6000;
  BroadcastServerIPv6.MulticastGroup := 'FF02:0:0:0:0:0:0:1';
  BroadcastServerIPv6.Active := True;

  BroadcastListenerIPv6.DefaultPort := 6000;
  for I := 0 to BroadcastListenerIPv6.Bindings.Count - 1 do
  begin
    BroadcastListenerIPv6.Bindings.Items[I].Port := BroadcastListenerIPv6.DefaultPort;
    BroadcastListenerIPv6.Bindings.Items[I].IP := LIP;
  end;
  BroadcastListenerIPv6.MulticastGroup := 'FF02:0:0:0:0:0:0:1';
  BroadcastListenerIPv6.Active := True;
end;
when I say "only" I mean that BroadcastListenerIPv6.Bindings.Count = 1
I've been through iterations of this before, one where I've created Bindings for each IPv6 address that the device has.. always results the same: error 49
I'm about to resort to using:
https://github.com/robbiehanson/CocoaAsyncSocket
at least for iOS
DelphiWorlds
@DelphiWorlds
I'd rather not though.. having single source has advantages, however when I've fought with this as much as I have, it might be time to move on
Remy Lebeau
@rlebeau
@DelphiWorlds Are you setting either BroadcastListenerrIPv6.IPVersion := Id_IPv6 or BroadcastListenerIPv6.Bindings.Items[I].IPVersion := Id_IPv6 to match the IP you are assigning? Why do you have a Binding created at design-time if you are just going to overwrite it at runtime? You may as well just use Bindings.Add() at runtime instead.
DelphiWorlds
@DelphiWorlds
Revised code:
const
  cMulticastGroupIPv6 = 'FF02:0:0:0:0:0:0:1';

procedure TForm1.FormCreate(Sender: TObject);
var
  I: Integer;
  LBinding: TIdSocketHandle;
begin
  FLocalAddresses := TIdStackLocalAddressList.Create;
  GStack.GetLocalAddressList(FLocalAddresses);

  BroadcastServerIPv6.Port := 6000;
  BroadcastServerIPv6.MulticastGroup := cMulticastGroupIPv6;
  BroadcastServerIPv6.Active := True;

  BroadcastListenerIPv6.DefaultPort := 6000;
  BroadcastListenerIPv6.IPVersion := TIdIPVersion.Id_IPv6;
  BroadcastListenerIPv6.MulticastGroup := cMulticastGroupIPv6;
  BroadcastListenerIPv6.Bindings.Clear;
  for I := 0 to FLocalAddresses.Count - 1 do
  begin
    if FLocalAddresses[I].IPVersion = TIdIPVersion.Id_IPv6 then
    begin
      LBinding := BroadcastListenerIPv6.Bindings.Add;
      LBinding.IP := FLocalAddresses[I].IPAddress;
      LBinding.IPVersion := TIdIPVersion.Id_IPv6;
      LBinding.Port := BroadcastListenerIPv6.DefaultPort;
    end;
  end;
  BroadcastListenerIPv6.Active := True;
end;
Just so that it's clear what is and is not being set
Remy Lebeau
@rlebeau
@DelphiWorlds and? what happens with it? If it is still not working, I don't know what else to tell you. I've only worked with multicast once before, but it was on Windows using IPv4, and I didn't use Indy for it, I used straight Winsock calls. But TIdIPMCastClient basically makes the same Winsock calls I did. The only difference being that I also enabled the SO_REUSEADDR option (the ReuseSocket property in Indy), but I don't think that is a factor in your situation. Try talking to Apple about your error.
DelphiWorlds
@DelphiWorlds
same error, i.e. error 49.
DelphiWorlds
@DelphiWorlds
I may have solved the binding issue, however unless another issue I'm having is resolved, it'll be rather moot. I've posted to the delphi.internet.winsock group in the forums and posted an attachment to the attachments group which illustrates the issue, which is happening on Windows, before I've even tried any other platforms
mezen
@mezen
Is there a Delphi equivalent to this powershell code?
$fqdn = [System.Net.Dns]::GetHostEntry("host-name-goes-here").HostName
Kudzu
@czhower
The Indy DNS compononent can do that.
mezen
@mezen
TIdDNSResolver needs a DNS Server in Host, the powershell code does not. I have 2 network cards here with each card has multiple dns server set. What to do?
Kudzu
@czhower
You can read the system dns from the registry or use any DNS server as they area all public. Google DNS is 8.8.8.8 and 8.8.4.4
mezen
@mezen
Google DNS does not help with LAN Requests :(
Kudzu
@czhower
Then you need to use the winapi or registry to find your local dns server.