| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 |
- { $HDR$}
- {**********************************************************************}
- { Unit archived using Team Coherence }
- { Team Coherence is Copyright 2002 by Quality Software Components }
- { }
- { For further information / comments, visit our WEB site at }
- { http://www.TeamCoherence.com }
- {**********************************************************************}
- {}
- { $Log: 10223: IdIPMCastServer.pas
- {
- { Rev 1.0 2002.11.12 10:43:20 PM czhower
- }
- unit IdIPMCastServer;
- {
- History:
- Date By Description
- ---------- ---------- --------------------------------------------------
- 2001-10-16 DSiders Modified TIdIPMCastServer.MulticastBuffer to
- validate the AHost argument to the method instead
- of the MulticastGroup property.
- ??? Dr. Harley J. Mackenzie Initial revision.
- }
- interface
- uses
- Classes,
- IdIPMCastBase, IdComponent, IdSocketHandle;
- const
- DEF_IMP_LOOPBACK = True;
- DEF_IMP_TTL = 1;
- type
- TIdIPMCastServer = class(TIdIPMCastBase)
- protected
- FBinding: TIdSocketHandle;
- FBoundIP: String;
- FBoundPort: Integer;
- FLoopback: Boolean;
- FTimeToLive: Byte;
- //
- procedure CloseBinding; override;
- function GetActive: Boolean; override;
- function GetBinding: TIdSocketHandle; override;
- procedure Loaded; override;
- procedure MulticastBuffer(AHost: string; const APort: Integer; var ABuffer; const AByteCount: integer);
- procedure SetLoopback(const AValue: Boolean); virtual;
- procedure SetLoopbackOption(InBinding: TIdSocketHandle; const Value: Boolean); virtual;
- procedure SetTTL(const Value: Byte); virtual;
- procedure SetTTLOption(InBinding: TIdSocketHandle; const Value: Byte); virtual;
- public
- constructor Create(AOwner: TComponent); override;
- procedure Send(AData: string);
- procedure SendBuffer(var ABuffer; const AByteCount: integer);
- destructor Destroy; override;
- //
- property Binding: TIdSocketHandle read GetBinding;
- published
- property Active;
- property BoundIP: String read FBoundIP write FBoundIP;
- property BoundPort: Integer read FBoundPort write FBoundPort;
- property Loopback: Boolean read FLoopback write SetLoopback default DEF_IMP_LOOPBACK;
- property MulticastGroup;
- property Port;
- property TimeToLive: Byte read FTimeToLive write SetTTL default DEF_IMP_TTL;
- end;
- implementation
- { TIdIPMCastServer }
- uses
- IdResourceStrings, IdStack, IdStackConsts, IdGlobal, SysUtils;
- constructor TIdIPMCastServer.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- FLoopback := DEF_IMP_LOOPBACK;
- FTimeToLive := DEF_IMP_TTL;
- end;
- procedure TIdIPMCastServer.CloseBinding;
- var
- Multicast: TMultiCast;
- begin
- Multicast.IMRMultiAddr := GStack.StringToTInAddr(FMulticastGroup);
- Multicast.IMRInterface.S_addr := Id_INADDR_ANY;
- FBinding.SetSockOpt(Id_IPPROTO_IP, Id_IP_DROP_MEMBERSHIP, pchar(@Multicast), SizeOf(Multicast));
- FreeAndNil(FBinding);
- end;
- function TIdIPMCastServer.GetActive: Boolean;
- begin
- Result := inherited GetActive or (Assigned(FBinding) and FBinding.HandleAllocated);
- end;
- function TIdIPMCastServer.GetBinding: TIdSocketHandle;
- var
- Multicast: TMultiCast;
- begin
- if not Assigned(FBinding) then begin
- FBinding := TIdSocketHandle.Create(nil);
- end;
- if not FBinding.HandleAllocated then begin
- FBinding.AllocateSocket(Id_SOCK_DGRAM);
- FBinding.IP := FBoundIP;
- FBinding.Port := FBoundPort;
- FBinding.Bind;
- Multicast.IMRMultiAddr := GStack.StringToTInAddr(FMulticastGroup);
- Multicast.IMRInterface.S_addr := Id_INADDR_ANY;
- FBinding.SetSockOpt(Id_IPPROTO_IP, Id_IP_ADD_MEMBERSHIP, pchar(@Multicast), SizeOf(Multicast));
- SetTTLOption(FBinding, FTimeToLive);
- SetLoopbackOption(FBinding, FLoopback);
- end;
- Result := FBinding;
- end;
- procedure TIdIPMCastServer.Loaded;
- var
- b: Boolean;
- begin
- inherited Loaded;
- b := FDsgnActive;
- FDsgnActive := False;
- Active := b;
- end;
- procedure TIdIPMCastServer.MulticastBuffer(AHost: string; const APort: Integer; var ABuffer; const AByteCount: integer);
- begin
- // DS - if not IsValidMulticastGroup(FMulticastGroup) then
- if not IsValidMulticastGroup(AHost) then
- raise EIdMCastNotValidAddress.Create(RSIPMCastInvalidMulticastAddress);
- Binding.SendTo(AHost, APort, ABuffer, AByteCount);
- end;
- procedure TIdIPMCastServer.Send(AData: string);
- begin
- MulticastBuffer(FMulticastGroup, FPort, PChar(AData)^, Length(AData));
- end;
- procedure TIdIPMCastServer.SendBuffer(var ABuffer; const AByteCount: integer);
- begin
- MulticastBuffer(FMulticastGroup, FPort, ABuffer, AByteCount);
- end;
- procedure TIdIPMCastServer.SetLoopback(const AValue: Boolean);
- var
- LThisLoopback: Integer;
- begin
- if FLoopback <> AValue then begin
- FLoopback := AValue;
- SetLoopbackOption(FBinding, AValue);
- end;
- end;
- procedure TIdIPMCastServer.SetLoopbackOption(InBinding: TIdSocketHandle; const Value: Boolean);
- var
- LThisLoopback: Integer;
- begin
- if Assigned(InBinding) and InBinding.HandleAllocated then begin
- LThisLoopback := iif(Value, 1, 0);
- InBinding.SetSockOpt(Id_IPPROTO_IP, Id_IP_MULTICAST_LOOP, PChar(@LThisLoopback), SizeOf(LThisLoopback));
- end;
- end;
- procedure TIdIPMCastServer.SetTTL(const Value: Byte);
- begin
- if (FTimeToLive <> Value) then begin
- FTimeToLive := Value;
- SetTTLOption(FBinding, Value);
- end;
- end;
- procedure TIdIPMCastServer.SetTTLOption(InBinding: TIdSocketHandle; const Value: Byte);
- var
- LThisTTL: Integer;
- begin
- if Assigned(InBinding) and InBinding.HandleAllocated then begin
- LThisTTL := Value;
- InBinding.SetSockOpt(Id_IPPROTO_IP, Id_IP_MULTICAST_TTL, PChar(@LThisTTL), SizeOf(LThisTTL));
- end;
- end;
- destructor TIdIPMCastServer.Destroy;
- begin
- Active := False;
- inherited Destroy;
- end;
- end.
|