source: trunk/Demo/Packages/CoolWeb/Network/UTCPServer.pas

Last change on this file was 60, checked in by chronos, 12 years ago
File size: 3.7 KB
Line 
1unit UTCPServer;
2
3{$mode Delphi}{$H+}
4
5interface
6
7uses
8 Classes, SysUtils,
9 {$IFDEF WINDOWS}
10 WinSock,
11 {$ELSE}
12 baseunix, sockets,
13 //LibC,
14 {$ENDIF}
15 BlckSock, UPool, UResetableThread;
16
17type
18 TTCPServer = class;
19
20 { TTCPClientThread }
21
22 TTCPClientThread = class(TResetableThread)
23 Parent: TTCPServer;
24 Socket: TTCPBlockSocket;
25 procedure Execute;
26 constructor Create;
27 destructor Destroy; override;
28 end;
29
30 { TClientThreadedPool }
31
32 TClientThreadedPool = class(TThreadPool)
33 protected
34 function NewItemObject: TObject; override;
35 private
36 FActive: Boolean;
37 procedure SetActive(const AValue: Boolean);
38 public
39 property Active: Boolean read FActive write SetActive;
40 end;
41
42 { TAcceptThread }
43
44 TAcceptThread = class(TThread)
45 Parent: TTCPServer;
46 procedure Execute; override;
47 end;
48
49 { TTCPServer }
50
51 TTCPServer = class
52 private
53 FOnClientConnect: TNotifyEvent;
54 Socket: TTCPBlockSocket;
55 FActive: Boolean;
56 AcceptThread: TAcceptThread;
57 procedure SetActive(const AValue: Boolean);
58 public
59 ThreadPool: TClientThreadedPool;
60 Address: string;
61 Port: Word;
62 constructor Create;
63 destructor Destroy; override;
64 property Active: Boolean read FActive write SetActive;
65 property OnClientConnect: TNotifyEvent read FOnClientConnect
66 write FOnClientConnect;
67 end;
68
69implementation
70
71{ TTCPServer }
72
73procedure TTCPServer.SetActive(const AValue: Boolean);
74begin
75 if AValue and not FActive then begin
76 with Socket do begin
77 ThreadPool.Active := True;
78 CreateSocket;
79 SetLinger(True, 10);
80 WriteLn(Address + ':' + IntToStr(Port));
81 Bind(Address, IntToStr(Port));
82 WriteLn(LastError);
83 if LastError <> 0 then raise Exception.Create('Socket bind error');
84 Listen;
85 if LastError <> 0 then raise Exception.Create('Socket listen error');
86 AcceptThread := TAcceptThread.Create(True);
87 AcceptThread.Parent := Self;
88 AcceptThread.FreeOnTerminate := False;
89 AcceptThread.Resume;
90 end;
91 end else
92 if not AValue and FActive then begin
93 with Socket do begin
94 AcceptThread.Terminate;
95 AcceptThread.WaitFor;
96 AcceptThread.Destroy;
97 ThreadPool.Active := False;
98 CloseSocket;
99 end;
100 end;
101 FActive := AValue;
102end;
103
104constructor TTCPServer.Create;
105begin
106 ThreadPool := TClientThreadedPool.Create;
107 ThreadPool.TotalCount := 10;
108 ThreadPool.Active := True;
109
110 Socket := TTCPBlockSocket.Create;
111 Address := '0.0.0.0';
112 Port := 80;
113end;
114
115destructor TTCPServer.Destroy;
116begin
117 ThreadPool.Destroy;
118 Active := False;
119 Socket.Destroy;
120 inherited Destroy;
121end;
122
123{ TAcceptThread }
124
125procedure TAcceptThread.Execute;
126var
127 NewSocket: TSocket;
128 NewObject: TTCPClientThread;
129begin
130 repeat
131 if Parent.Socket.CanRead(1000) then begin
132 NewSocket := Parent.Socket.Accept;
133 if Parent.Socket.LastError = 0 then begin
134 NewObject := TTCPClientThread(Parent.ThreadPool.Acquire);
135 NewObject.Parent := Parent;
136 NewObject.Socket.Socket := NewSocket;
137 NewObject.Start;
138 end;
139 end;
140 until Terminated;
141end;
142
143{ TTCPClientThread }
144
145procedure TTCPClientThread.Execute;
146begin
147 if Assigned(Parent.FOnClientConnect) then
148 Parent.FOnClientConnect(Self);
149
150 Parent.ThreadPool.Release(Self);
151end;
152
153constructor TTCPClientThread.Create;
154begin
155 inherited;
156 Method := Execute;
157 Socket := TTCPBlockSocket.Create;
158end;
159
160destructor TTCPClientThread.Destroy;
161begin
162 Socket.Destroy;
163 inherited;
164end;
165
166{ TClientThreadedPool }
167
168function TClientThreadedPool.NewItemObject: TObject;
169begin
170 Result := TTCPClientThread.Create;
171 TResetableThread(Result).OnException := ThreadException;
172end;
173
174procedure TClientThreadedPool.SetActive(const AValue: Boolean);
175begin
176 FActive := AValue;
177end;
178
179end.
180
Note: See TracBrowser for help on using the repository browser.