forked from IndySockets/Indy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
IdIPMCastServer.pas
219 lines (185 loc) · 5.51 KB
/
IdIPMCastServer.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
{
$Project$
$Workfile$
$Revision$
$DateUTC$
$Id$
This file is part of the Indy (Internet Direct) project, and is offered
under the dual-licensing agreement described on the Indy website.
(http://www.indyproject.org/)
Copyright:
(c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved.
}
{
$Log$
}
{
Rev 1.7 14/06/2004 21:38:42 CCostelloe
Converted StringToTIn4Addr call
Rev 1.6 09/06/2004 10:00:50 CCostelloe
Kylix 3 patch
Rev 1.5 2004.02.03 5:43:52 PM czhower
Name changes
Rev 1.4 1/21/2004 3:11:10 PM JPMugaas
InitComponent
Rev 1.3 10/26/2003 09:11:54 AM JPMugaas
Should now work in NET.
Rev 1.2 2003.10.24 10:38:28 AM czhower
UDP Server todos
Rev 1.1 2003.10.12 4:03:58 PM czhower
compile todos
Rev 1.0 11/13/2002 07:55:26 AM JPMugaas
2001-10-16 DSiders
Modified TIdIPMCastServer.MulticastBuffer to
validate the AHost argument to the method instead
of the MulticastGroup property.
}
unit IdIPMCastServer;
{
Dr. Harley J. Mackenzie, Initial revision.
}
interface
{$I IdCompilerDefines.inc}
//Put FPC into Delphi mode
uses
IdComponent,
IdGlobal,
IdIPMCastBase,
IdSocketHandle;
const
DEF_IMP_LOOPBACK = True;
DEF_IMP_TTL = 1;
type
TIdIPMCastServer = class(TIdIPMCastBase)
protected
FBinding: TIdSocketHandle;
FBoundIP: String;
FBoundPort: TIdPort;
FLoopback: Boolean;
FTimeToLive: Byte;
//
procedure ApplyLoopback;
procedure ApplyTimeToLive;
procedure CloseBinding; override;
function GetActive: Boolean; override;
function GetBinding: TIdSocketHandle; override;
procedure MulticastBuffer(const AHost: string; const APort: Integer; const ABuffer : TIdBytes);
procedure SetLoopback(const AValue: Boolean); virtual;
procedure SetTTL(const AValue: Byte); virtual;
procedure InitComponent; override;
public
procedure Send(const AData: string; AByteEncoding: IIdTextEncoding = nil
{$IFDEF STRING_IS_ANSI}; ASrcEncoding: IIdTextEncoding = nil{$ENDIF}
); overload;
procedure Send(const ABuffer : TIdBytes); overload;
destructor Destroy; override;
//
property Binding: TIdSocketHandle read GetBinding;
published
property Active;
property BoundIP: String read FBoundIP write FBoundIP;
property BoundPort: TIdPort read FBoundPort write FBoundPort;
property Loopback: Boolean read FLoopback write SetLoopback default DEF_IMP_LOOPBACK;
property MulticastGroup;
property IPVersion default ID_DEFAULT_IP_VERSION;
property Port;
property ReuseSocket;
property TimeToLive: Byte read FTimeToLive write SetTTL default DEF_IMP_TTL;
end;
implementation
{ TIdIPMCastServer }
uses
IdResourceStringsCore,
IdStack,
IdStackConsts,
SysUtils;
procedure TIdIPMCastServer.InitComponent;
begin
inherited InitComponent;
FLoopback := DEF_IMP_LOOPBACK;
FTimeToLive := DEF_IMP_TTL;
end;
destructor TIdIPMCastServer.Destroy;
begin
Active := False;
inherited Destroy;
end;
procedure TIdIPMCastServer.CloseBinding;
begin
FreeAndNil(FBinding);
end;
function TIdIPMCastServer.GetActive: Boolean;
begin
if IsDesignTime then begin
// inherited GetActive keeps track of design-time Active property
Result := inherited GetActive;
end else begin
Result := Assigned(FBinding);
if Result then begin
Result := FBinding.HandleAllocated;
end;
end;
end;
function TIdIPMCastServer.GetBinding: TIdSocketHandle;
begin
if not Assigned(FBinding) then begin
FBinding := TIdSocketHandle.Create(nil);
end;
if not FBinding.HandleAllocated then begin
FBinding.IPVersion := FIPVersion;
FBinding.AllocateSocket(Id_SOCK_DGRAM);
FBinding.IP := FBoundIP;
FBinding.Port := FBoundPort;
FBinding.ReuseSocket := FReuseSocket;
FBinding.Bind;
//TODO: FBinding.EnableMulticastInterface;
ApplyTimeToLive;
ApplyLoopback;
end;
Result := FBinding;
end;
procedure TIdIPMCastServer.MulticastBuffer(const AHost: string; const APort: Integer; const ABuffer : TIdBytes);
begin
// DS - if not IsValidMulticastGroup(FMulticastGroup) then
if not IsValidMulticastGroup(AHost) then begin
raise EIdMCastNotValidAddress.Create(RSIPMCastInvalidMulticastAddress);
end;
Binding.SendTo(AHost, APort, ABuffer, Binding.IPVersion);
end;
procedure TIdIPMCastServer.Send(const AData: string; AByteEncoding: IIdTextEncoding = nil
{$IFDEF STRING_IS_ANSI}; ASrcEncoding: IIdTextEncoding = nil{$ENDIF}
);
begin
MulticastBuffer(FMulticastGroup, FPort, ToBytes(AData, AByteEncoding{$IFDEF STRING_IS_ANSI}, ASrcEncoding{$ENDIF}));
end;
procedure TIdIPMCastServer.Send(const ABuffer : TIdBytes);
begin
MulticastBuffer(FMulticastGroup, FPort, ABuffer);
end;
procedure TIdIPMCastServer.SetLoopback(const AValue: Boolean);
begin
if FLoopback <> AValue then begin
FLoopback := AValue;
ApplyLoopback;
end;
end;
procedure TIdIPMCastServer.SetTTL(const AValue: Byte);
begin
if FTimeToLive <> AValue then begin
FTimeToLive := AValue;
ApplyTimeToLive;
end;
end;
procedure TIdIPMCastServer.ApplyLoopback;
begin
if Assigned(FBinding) and FBinding.HandleAllocated then begin
FBinding.SetLoopBack(FLoopback);
end;
end;
procedure TIdIPMCastServer.ApplyTimeToLive;
begin
if Assigned(FBinding) and FBinding.HandleAllocated then begin
FBinding.SetMulticastTTL(FTimeToLive);
end;
end;
end.