6 uses KOL
,KOLClasses
{ ,
8 IdComponent
{, IdException}, IdSocketHandle
, IdTCPConnection
, IdThread
,
9 IdThreadMgr
, IdThreadMgrDefault
,
13 TOperation
= (opInsert
, opRemove
);
15 { TIdTCPServer = object(TObj)
18 PIdTCPServer=^TIdTCPServer;
21 TIdListenerThread
= object(TIdThread
)
24 FBindingList
: PList
;//TList;
25 FServer
,FAServer
: PObj
;//TIdTCPServer;
27 procedure Init
; virtual;
28 procedure AfterRun
; virtual;// override;
29 { constructor Create(axServer: TIdTCPServer); }// reintroduce;
31 virtual; procedure Run
; virtual;// override;
33 property AcceptWait
: integer read FAcceptWait write FAcceptWait
;
34 property Server
: {TIdTCPServer}PObj read FServer
;
36 PIdListenerThread
=^TIdListenerThread
;
37 //function NewIdListenerThread(axServer: PIdTCPServer):PIdListenerThread;
40 TIdTCPServerConnection
= object(TIdTCPConnection
)
42 function GetServer
: PObj
;//TIdTCPServer;
45 procedure Init
; virtual;
46 property Server
: {TIdTCPServer}PObj read GetServer
;
49 PIdTCPServerConnection
=^TIdTCPServerConnection
;
50 function NewIdTCPServerConnection(AOwner
: PObj
):PIdTCPServerConnection
;
53 TIdPeerThread
= object(TIdThread
)
55 FConnection
: PIdTCPServerConnection
;//TIdTCPServerConnection;
57 procedure AfterRun
; virtual;// override;
58 procedure BeforeRun
; virtual;// override;
60 procedure Run
; virtual;//override;
61 property Connection
: PIdTCPServerConnection
{TIdTCPServerConnection} read FConnection
;
63 PIdPeerThread
=^TIdPeerThread
; type
65 TIdServerThreadEvent
= procedure(AThread
: PIdPeerThread
{TIdPeerThread}) of object;
67 TIdTCPServer
= object(TIdComponent
)
70 FActive
, FImplicitThreadMgrCreated
: Boolean;
71 FThreadMgr
: PIdThreadMgr
;//TIdThreadMgr;
72 FBindings
: PIdSocketHandles
;//TIdSocketHandles;
73 FListenerThread
: PIdListenerThread
;//TIdListenerThread;
74 FTerminateWaitTime
: Integer;
75 // FThreadClass: TIdThreadClass;
76 FThreads
: PThreadList
;//TThreadList;
77 FOnExecute
, FOnConnect
, FOnDisconnect
: TIdServerThreadEvent
;
79 FIntercept
: PIdServerIntercept
;//TIdServerIntercept;
80 procedure DoConnect(axThread
: PIdPeerThread
{TIdPeerThread}); virtual;
81 procedure DoDisconnect(axThread
: PIdPeerThread
{TIdPeerThread}); virtual;
82 function DoExecute(AThread
:PIdPeerThread
{TIdPeerThread}): boolean; virtual;
83 function GetDefaultPort
: integer;
84 procedure Notification(AComponent
: PObj
{TComponent}; Operation
: TOperation
); virtual;// override;
85 procedure SetAcceptWait(AValue
: integer);
86 procedure SetActive(AValue
: Boolean); virtual;
87 procedure SetBindings(const abValue
: PIdSocketHandles
{TIdSocketHandles});
88 procedure SetDefaultPort(const AValue
: integer);
89 procedure SetIntercept(const Value
: PIdServerIntercept
{TIdServerIntercept});
90 procedure SetThreadMgr(const Value
: PIdThreadMgr
{TIdThreadMgr});
91 procedure TerminateAllThreads
;
93 procedure Init
; virtual;
94 { constructor Create(AOwner: TComponent); override;
96 virtual; procedure Loaded
; virtual;//override;
97 property AcceptWait
: integer read FAcceptWait write SetAcceptWait
;
98 property ImplicitThreadMgrCreated
: Boolean read FImplicitThreadMgrCreated
;
99 // property ThreadClass: TIdThreadClass read FThreadClass write FThreadClass;
100 property Threads
: PThreadList
{TThreadList} read FThreads
;
102 property Active
: boolean read FActive write SetActive default
False;
103 property Bindings
: PIdSocketHandles
{TIdSocketHandles }read FBindings write SetBindings
;
104 property DefaultPort
: integer read GetDefaultPort write SetDefaultPort
;
105 property Intercept
: PIdServerIntercept
{TIdServerIntercept} read FIntercept write SetIntercept
;
106 property OnConnect
: TIdServerThreadEvent read FOnConnect write FOnConnect
;
107 property OnExecute
: TIdServerThreadEvent read FOnExecute write FOnExecute
;
108 property OnDisconnect
: TIdServerThreadEvent read FOnDisconnect write
110 property TerminateWaitTime
: Integer read FTerminateWaitTime write
113 property ThreadMgr
: PIdThreadMgr
{TIdThreadMgr} read FThreadMgr write SetThreadMgr
;
116 PIdTCPServer
=^TIdTCPServer
;
118 function NewIdListenerThread(axServer
: PIdTCPServer
):PIdListenerThread
;
119 function NewIdTCPServer(AOwner
: PControl
):PIdTCPServer
;
120 { type MyStupid27292=DWord;
121 EIdTCPServerError = object(EIdException);
122 PdTCPServer=^IdTCPServer; type MyStupid67165=DWord;
123 EIdAcceptWaitCannotBeModifiedWhileServerIsActive = object(EIdTCPServerError);
124 PTCPServer=^dTCPServer; type MyStupid31869=DWord;
125 EIdNoExecuteSpecified = object(EIdTCPServerError);
126 PCPServer=^TCPServer; type MyStupid16179=DWord;
131 IdGlobal
, IdResourceStrings
, IdStack
, IdStackConsts
;
133 //constructor TIdTCPServer.Create(AOwner: TComponent);
134 function NewIdTCPServer(AOwner
: PControl
):PIdTCPServer
;
137 New( Result
, Create
);
142 FTerminateWaitTime := 5000;
143 // FThreads := TThreadList.Create;
144 // FBindings := TIdSocketHandles.Create(Self);
145 // FThreadClass := TIdPeerThread;
149 destructor TIdTCPServer
.Destroy
;
153 FreeAndNil(FBindings
);
154 FreeAndNil(FThreads
);
158 procedure TIdTCPServer
.DoConnect(axThread
: PIdPeerThread
{TIdPeerThread});
160 if assigned(OnConnect
) then
166 procedure TIdTCPServer
.DoDisconnect(axThread
: PIdPeerThread
{TIdPeerThread});
168 if assigned(OnDisconnect
) then
170 OnDisconnect(axThread
);
174 function TIdTCPServer
.DoExecute(AThread
: PIdPeerThread
{TIdPeerThread}): boolean;
176 result
:= assigned(OnExecute
);
183 function TIdTCPServer
.GetDefaultPort
: integer;
185 result
:= FBindings
.DefaultPort
;
188 procedure TIdTCPServer
.Init
;
194 FTerminateWaitTime
:= 5000;
195 FThreads
:= NewThreadList();//TThreadList.Create;
196 FBindings
:= NewIdSocketHandles(@Self
);//TIdSocketHandles.Create(Self);
197 // FThreadClass := TIdPeerThread;
201 procedure TIdTCPServer
.Loaded
;
211 procedure TIdTCPServer
.Notification(AComponent
: PObj
{TComponent}; Operation
:
215 if (Operation
= opRemove
) then
217 if (AComponent
= FThreadMgr
) then
222 if (AComponent
= FIntercept
) then
229 procedure TIdTCPServer
.SetAcceptWait(AValue
: integer);
234 // EIdAcceptWaitCannotBeModifiedWhileServerIsActive.Create(RSAcceptWaitCannotBeModifiedWhileServerIsActive);
236 FAcceptWait
:= AValue
;
239 procedure TIdTCPServer
.SetActive(AValue
: Boolean);
243 { if (not (csDesigning in ComponentState)) and (FActive <> AValue)
244 and (not (csLoading in ComponentState)) then}
248 if Bindings
.Count
= 0 then
253 for i
:= 0 to Bindings
.Count
- 1 do
255 with Bindings
.Items
[i
]^ do
258 SetSockOpt(Id_SOL_SOCKET
, Id_SO_REUSEADDR
, PChar(@Id_SO_True
),
265 FImplicitThreadMgrCreated
:= not assigned(ThreadMgr
);
266 if ImplicitThreadMgrCreated
then
268 ThreadMgr
:= NewIdThreadMgrDefault(@Self
);//TIdThreadMgrDefault.Create(Self);
270 // ThreadMgr.ThreadClass := ThreadClass;
271 FListenerThread
:= NewIdListenerThread(@Self
);//TIdListenerThread.Create(Self);
272 FListenerThread
.AcceptWait
:= AcceptWait
;
273 FListenerThread
.Start
;
277 FListenerThread
.Stop
;
278 for i
:= 0 to Bindings
.Count
- 1 do
280 Bindings
.Items
[i
].CloseSocket(False);
283 if ImplicitThreadMgrCreated
then
285 FreeAndNil(FThreadMgr
);
287 FImplicitThreadMgrCreated
:= false;
289 FListenerThread
.WaitFor
;
290 FListenerThread
.Free
;
296 procedure TIdTCPServer
.SetBindings(const abValue
: PIdSocketHandles
{TIdSocketHandles});
298 FBindings
.Assign(abValue
);
301 procedure TIdTCPServer
.SetDefaultPort(const AValue
: integer);
303 FBindings
.DefaultPort
:= AValue
;
306 procedure TIdTCPServer
.SetIntercept(const Value
: PIdServerIntercept
{TIdServerIntercept});
309 if assigned(FIntercept
) then
311 // FIntercept.FreeNotification(@Self);
315 procedure TIdTCPServer
.SetThreadMgr(const Value
: PIdThreadMgr
{TIdThreadMgr});
320 // Value.FreeNotification(@self);
324 procedure TIdTCPServer
.TerminateAllThreads
;
328 Thread
: PIdPeerThread
;//TIdPeerThread;
330 LSleepTime
: integer = 250;
332 list
:= Threads
.LockList
;
334 for i
:= 0 to list
.Count
- 1 do
336 Thread
:= PIdPeerThread
{TIdPeerThread}(list
.items
[i
]);
337 Thread
.Connection
.DisconnectSocket
;
339 finally{ Threads.UnlockList};
341 for i
:= 1 to (TerminateWaitTime
div LSleepTime
) do
344 list
:= Threads
.LockList
;
346 if list
.Count
= 0 then
350 finally {Threads.UnlockList};
355 procedure TIdListenerThread
.AfterRun
;
360 for i
:= PIdTCPServer(Server
).Bindings
.Count
- 1 downto 0 do
362 PIdTCPServer(Server
).Bindings
.Items
[i
].CloseSocket
;
366 //constructor TIdListenerThread.Create(axServer: TIdTCPServer);
367 function NewIdListenerThread(axServer
: PIdTCPServer
):PIdListenerThread
;
370 New( Result
, Create
);
371 Result
.FAServer
:=axServer
;
375 FBindingList := NewList();//TList.Create;
380 destructor TIdListenerThread
.Destroy
;
386 procedure TIdListenerThread
.Init
;
391 FBindingList
:= NewList();//TList.Create;
392 FServer
:= FAServer
;//axServer;
396 procedure TIdListenerThread
.Run
;
398 Peer
: PIdTCPServerConnection
;//TIdTCPServerConnection;
399 Thread
: PIdPeerThread
;//TIdPeerThread;
403 for i
:= 0 to PIdTCPServer(Server
).Bindings
.Count
- 1 do
405 FBindingList
.Add({TObject}PObj(PIdTCPServer(Server
).Bindings
.Items
[i
].Handle
));
407 if GStack
.WSSelect(FBindingList
, nil, nil, AcceptWait
) > 0 then
409 if not Terminated
then
411 for i
:= 0 to FBindingList
.Count
- 1 do
413 Peer
:= NewIdTCPServerConnection(@Self
);//TIdTCPServerConnection.Create(Server);
416 Binding
.Accept(TIdStackSocketHandle(FBindingList
.Items
[i
]));
417 if Assigned(PIdTCPServer(Server
).Intercept
) then
420 Peer
.Intercept
:= PIdTCPServer(Server
).Intercept
.Accept(Binding
);
421 Peer
.InterceptEnabled
:= True;
429 Thread
:=PIdPeerThread(PIdTCPServer(Server
).ThreadMgr
.GetThread
);// TIdPeerThread(Server.ThreadMgr.GetThread);
430 Thread
.FConnection
:= Peer
;
431 PIdTCPServer(Server
).Threads
.Add(Thread
);
439 function TIdTCPServerConnection
.GetServer
: PObj
;//TIdTCPServer;
441 result
:= PIdTCPServer(FOwner
);// as TIdTCPServer;
444 procedure TIdPeerThread
.AfterRun
;
446 with PIdTCPServer(Connection
.Server
)^ do
449 ThreadMgr
.ReleaseThread(@Self
);
450 Threads
.Remove(@Self
);
452 FreeAndNil(FConnection
);
455 procedure TIdPeerThread
.BeforeRun
;
457 PIdTCPServer(Connection
.Server
).DoConnect(@Self
);
460 procedure TIdPeerThread
.Run
;
463 if not PIdTCPServer(Connection
.Server
).DoExecute(@Self
) then
465 // raise EIdNoExecuteSpecified.Create(RSNoExecuteSpecified);
468 on E: EIdSocketError do
473 Connection.Disconnect;
476 on EIdClosedSocket do ;
480 if not Connection
.Connected
then
486 function NewIdTCPServerConnection(AOwner
: PObj
):PIdTCPServerConnection
;
488 New( Result
, Create
);
492 procedure TIdTCPServerConnection
.Init
;