source: tags/1.3.0/UTCP.pas

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