source: branches/DirectWeb/UTCPServer.pas

Last change on this file was 89, checked in by george, 14 years ago
  • Opraveno: Chybné vytváření pojmenovaných objektů TEvent.
  • Opraveno: Chybné přidělování a uvolňování zásobníků vláken a databázových spojení.
  • Opraveno: Chybná inicializace parametrů databázových spojení.
File size: 3.9 KB
Line 
1unit UTCPServer;
2
3{$mode objfpc}{$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; override;
26 constructor Create;
27 destructor Destroy; override;
28 end;
29
30 { TClientThreadedPool }
31
32 TClientThreadedPool = class(TThreadedPool)
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 Socket: TTCPBlockSocket;
53 FActive: Boolean;
54 AcceptThread: TAcceptThread;
55 procedure SetActive(const AValue: Boolean);
56 public
57 ThreadPool: TClientThreadedPool;
58 Address: string;
59 Port: Word;
60 constructor Create;
61 destructor Destroy; override;
62 property Active: Boolean read FActive write SetActive;
63 property OnClientConnect: TNotifyEvent read FOnClientConnect
64 write FOnClientConnect;
65 end;
66
67implementation
68
69{ TTCPServer }
70
71procedure TTCPServer.SetActive(const AValue: Boolean);
72begin
73 if AValue and not FActive then begin
74 with Socket do begin
75 ThreadPool.Active := True;
76 CreateSocket;
77 SetLinger(True, 10);
78 WriteLn(Address + ':' + IntToStr(Port));
79 Bind(Address, IntToStr(Port));
80 WriteLn(LastError);
81 if LastError <> 0 then raise Exception.Create('Socket bind error');
82 Listen;
83 if LastError <> 0 then raise Exception.Create('Socket listen error');
84 AcceptThread := TAcceptThread.Create(True);
85 AcceptThread.Parent := Self;
86 AcceptThread.FreeOnTerminate := False;
87 AcceptThread.Resume;
88 end;
89 end else
90 if not AValue and FActive then begin
91 with Socket do begin
92 AcceptThread.Terminate;
93 AcceptThread.WaitFor;
94 AcceptThread.Destroy;
95 ThreadPool.Active := False;
96 CloseSocket;
97 end;
98 end;
99 FActive := AValue;
100end;
101
102constructor TTCPServer.Create;
103begin
104 ThreadPool := TClientThreadedPool.Create;
105 ThreadPool.TotalCount := 10;
106 ThreadPool.Active := True;
107
108 Socket := TTCPBlockSocket.Create;
109 Address := '0.0.0.0';
110 Port := 80;
111end;
112
113destructor TTCPServer.Destroy;
114begin
115 ThreadPool.Destroy;
116 Active := False;
117 Socket.Destroy;
118 inherited Destroy;
119end;
120
121{ TAcceptThread }
122
123procedure TAcceptThread.Execute;
124var
125 NewSocket: TSocket;
126 NewObject: TTCPClientThread;
127begin
128 repeat
129 if Parent.Socket.CanRead(1000) then begin
130 NewSocket := Parent.Socket.Accept;
131 if Parent.Socket.LastError = 0 then begin
132 NewObject := TTCPClientThread(Parent.ThreadPool.Acquire);
133 NewObject.Parent := Parent;
134 NewObject.Socket.Socket := NewSocket;
135 NewObject.Start;
136 end;
137 end;
138 until Terminated;
139end;
140
141{ TTCPClientThread }
142
143procedure TTCPClientThread.Execute;
144begin
145 if Assigned(Parent.FOnClientConnect) then
146 Parent.FOnClientConnect(Self);
147
148 Parent.ThreadPool.Release(Self);
149end;
150
151constructor TTCPClientThread.Create;
152begin
153 inherited;
154 Socket := TTCPBlockSocket.Create;
155end;
156
157destructor TTCPClientThread.Destroy;
158begin
159 Socket.Destroy;
160 inherited;
161end;
162
163{ TClientThreadedPool }
164
165procedure TClientThreadedPool.SetActive(const AValue: Boolean);
166var
167 I: Integer;
168begin
169 if not FActive and AValue then begin
170 for I := 0 to TotalCount - 1 do begin
171 TThreadedPoolItem(Items[I]).Item := TTCPClientThread.Create;
172 end;
173 end else
174 if FActive and not AValue then begin
175
176 end;
177 FActive := AValue;
178end;
179
180end.
181
Note: See TracBrowser for help on using the repository browser.