source: trunk/TCP.pas

Last change on this file was 318, checked in by chronos, 6 months ago
  • Modified: Code cleanup.
File size: 4.5 KB
Line 
1unit TCP;
2
3interface
4
5uses
6 Classes, SysUtils,
7 {$IFDEF WINDOWS}
8 WinSock,
9 {$ELSE}
10 baseunix, sockets,
11 //LibC,
12 {$ENDIF}
13 ssockets, fphttpserver, UPool, UResetableThread;
14
15type
16 TTCPServer = class;
17
18 { TTCPClientThread }
19
20 TTCPClientThread = class(TResetableThread)
21 Parent: TTCPServer;
22 Socket: TSocketStream;
23 procedure Execute;
24 constructor Create;
25 destructor Destroy; override;
26 end;
27
28 { TClientThreadedPool }
29
30 TClientThreadedPool = class(TThreadPool)
31 protected
32 function NewItemObject: TObject; override;
33 private
34 FActive: Boolean;
35 procedure SetActive(const AValue: Boolean);
36 public
37 property Active: Boolean read FActive write SetActive;
38 end;
39
40 { TAcceptThread }
41
42 TAcceptThread = class(TThread)
43 Parent: TTCPServer;
44 procedure Execute; override;
45 end;
46
47 { TTCPServer }
48
49 TTCPServer = class
50 private
51 FOnClientConnect: TNotifyEvent;
52 FSocket: TInetServer;
53 FActive: Boolean;
54 FAcceptThread: TAcceptThread;
55 procedure SetActive(const AValue: Boolean);
56 procedure ConnectExecute(Sender : TObject; Data : TSocketStream);
57 public
58 ThreadPool: TClientThreadedPool;
59 Address: string;
60 Port: Word;
61 constructor Create;
62 destructor Destroy; override;
63 property Active: Boolean read FActive write SetActive;
64 property OnClientConnect: TNotifyEvent read FOnClientConnect
65 write FOnClientConnect;
66 end;
67
68 { TTCPClient }
69
70 TTCPClient = class
71 private
72 FActive: Boolean;
73 FSocket: TInetSocket;
74 procedure SetActive(AValue: Boolean);
75 public
76 Address: string;
77 Port: Word;
78 constructor Create;
79 destructor Destroy; override;
80 property Socket: TInetSocket read FSocket;
81 property Active: Boolean read FActive write SetActive;
82 end;
83
84
85implementation
86
87{ TAcceptThread }
88
89procedure TAcceptThread.Execute;
90begin
91 Parent.FSocket.StartAccepting;
92end;
93
94{ TTCPClient }
95
96procedure TTCPClient.SetActive(AValue: Boolean);
97begin
98 if AValue and not FActive then begin
99 FSocket := TInetSocket.Create(Address, Port);
100 with FSocket do begin
101 Connect;
102 if LastError <> 0 then raise Exception.Create('Socket connect error');
103 end;
104 end else
105 if not AValue and FActive then begin
106 with FSocket do begin
107 FreeAndNil(FSocket);
108 end;
109 end;
110 FActive := AValue;
111end;
112
113constructor TTCPClient.Create;
114begin
115 FSocket := nil;
116 Address := '0.0.0.0';
117 Port := 80;
118end;
119
120destructor TTCPClient.Destroy;
121begin
122 Active := False;
123 DestroyFSocket);
124 inherited;
125end;
126
127{ TTCPServer }
128
129procedure TTCPServer.SetActive(const AValue: Boolean);
130begin
131 if AValue and not FActive then begin
132 ThreadPool.Active := True;
133 FSocket := TInetServer.Create(Address, Port);
134 //SetLinger(True, 10);
135 FSocket.OnConnect := ConnectExecute;
136 FSocket.Bind;
137 FSocket.Listen;
138 FAcceptThread := TAcceptThread.Create(True);
139 FAcceptThread.Parent := Self;
140 FAcceptThread.FreeOnTerminate := False;
141 FAcceptThread.Start;
142 end else
143 if not AValue and FActive then begin
144 FAcceptThread.Terminate;
145 FAcceptThread.WaitFor;
146 FreeAndNil(FAcceptThread);
147 ThreadPool.Active := False;
148 FreeAndNil(FSocket);
149 end;
150 FActive := AValue;
151end;
152
153constructor TTCPServer.Create;
154begin
155 ThreadPool := TClientThreadedPool.Create;
156 ThreadPool.TotalCount := 10;
157 ThreadPool.Active := True;
158
159 FSocket := nil;
160 Address := '0.0.0.0';
161 Port := 80;
162end;
163
164destructor TTCPServer.Destroy;
165begin
166 ThreadPool.Destroy;
167 Active := False;
168 inherited;
169end;
170
171procedure TTCPServer.ConnectExecute(Sender : TObject; Data : TSocketStream);
172var
173 NewSocket: TSocket;
174 NewObject: TTCPClientThread;
175begin
176 NewObject := TTCPClientThread(ThreadPool.Acquire);
177 NewObject.Parent := Self;
178 NewObject.Socket := Data;
179 NewObject.Start;
180end;
181
182{ TTCPClientThread }
183
184procedure TTCPClientThread.Execute;
185begin
186 if Assigned(Parent.FOnClientConnect) then
187 Parent.FOnClientConnect(Self);
188
189 Parent.ThreadPool.Release(Self);
190end;
191
192constructor TTCPClientThread.Create;
193begin
194 inherited;
195 Method := Execute;
196 Socket := nil;
197end;
198
199destructor TTCPClientThread.Destroy;
200begin
201 FreeAndNil(Socket);
202 inherited;
203end;
204
205{ TClientThreadedPool }
206
207function TClientThreadedPool.NewItemObject: TObject;
208begin
209 Result := TTCPClientThread.Create;
210 TResetableThread(Result).OnException := ThreadException;
211end;
212
213procedure TClientThreadedPool.SetActive(const AValue: Boolean);
214begin
215 FActive := AValue;
216end;
217
218end.
219
Note: See TracBrowser for help on using the repository browser.