2 / 2 / 0
Регистрация: 01.03.2010
Сообщений: 5
|
|
1
|
Многопотоковый сервер
19.03.2010, 10:21. Показов 1381. Ответов 0
Добрый день!
Суть программы проста - клиент принимает некоторое количество данных, затем отправляет их на сервер, а сервер заносит их в базу данных.
Использую компоненты TServerSocket и TClientSocket. Сервер установил в stThreadBlocking, клиент соответственно в ctBlocking. Проблема в том, единовременный что запрос от одного клиента обрабатывается нормально, от двух тоже, а вот если одновременно подключаются 3 и более - то сервер отвергает все подключения (несмотря на то, что ThreadCacheSize = 20);
Код сервера:
Delphi | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
| unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, DBTables, ExtCtrls, DBCtrls, Grids, DBGrids, XPMan, ScktComp,
StdCtrls;
type
TForm1 = class(TForm)
DBGrid1: TDBGrid;
DBNavigator1: TDBNavigator;
Table1: TTable;
DataSource1: TDataSource;
XPManifest1: TXPManifest;
ServerSocket1: TServerSocket;
Timer1: TTimer;
GroupBox1: TGroupBox;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
Label5: TLabel;
Label6: TLabel;
GroupBox2: TGroupBox;
Label7: TLabel;
Label8: TLabel;
Label9: TLabel;
Label10: TLabel;
GroupBox3: TGroupBox;
Label11: TLabel;
Label12: TLabel;
Label13: TLabel;
Label14: TLabel;
Edit1: TEdit;
procedure ServerSocket1GetThread(Sender: TObject;
ClientSocket: TServerClientWinSocket;
var SocketThread: TServerClientThread);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1; Online, day: integer;
implementation
Uses unit2;
{$R *.dfm}
procedure TForm1.ServerSocket1GetThread(Sender: TObject;
ClientSocket: TServerClientWinSocket;
var SocketThread: TServerClientThread);
begin
SocketThread := TServerThread.Create( FALSE, ClientSocket );
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
Label4.Caption:=inttostr(ServerSocket1.Socket.ActiveConnections);
Label5.Caption:=inttostr(ServerSocket1.Socket.ActiveThreads);
Label6.Caption:=inttostr(ServerSocket1.Socket.IdleThreads);
Label8.Caption:=inttostr(Table1.RecordCount);
Label10.Caption:=Edit1.Text;
Label13.Caption:=inttostr(Online);
Label14.Caption:=inttostr(Day);
end;
end. |
|
Юнит с потоком сервера:
Delphi | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
| unit Unit2;
interface
uses
windows, scktcomp, SysUtils, Classes, Forms;
type
EServerThread = class( Exception );
// serverthread это потомок TServerClientThread
TServerThread = class( TServerClientThread )
private
fSocketStream : TWinSocketStream;
public
procedure ClientExecute; override;
end;
var
ac, readlen,i,j : integer;
s:String;
c: array [0..255] of char;
implementation
uses Unit1;
procedure TServerThread.ClientExecute;
begin
inherited FreeOnTerminate := TRUE;
try
fSocketStream := TWinSocketStream.Create( ClientSocket, 1000 );
// 100000 - это таймаут в миллисекундах.
try
while ( not Terminated ) and ( ClientSocket.Connected ) do
try
if ( not Terminated ) and ( not fSocketStream.WaitForData( 10000 ) ) then
Break;
FillChar( c, 256, 0 );
ac := 0;
repeat
readlen := fSocketStream.Read( c[ac],256 );
// считываем блоки по 256 байт, до тех пор, пока буфер
// не заполнится
ac := ac+readlen;
until ( readlen = 0 ) or ( ac = 256 );
{Разделяем пакет на поля и добавляем записи в таблицу}
i:=1;
try
form1.Table1.insert;
form1.table1.Edit;
For j:=0 to 9 do
Begin
While c[i]<>#10 do
//#10 - разделяет данные отправляемые клиентом. Т.е. текст 10 Edit'ов сливаю в 1 пакет разделяя #10
begin
s:=s+c[i];
i:=i+1;
if c[i] = #10 then
Begin
i:=i+1;
Break;
end;
end;
form1.Table1.Fields.Fields[j].AsString:=s;
s:='';
end;
form1.Table1.Post;
Form1.Edit1.Text:= inttostr(Strtoint(Form1.Edit1.Text) + 1);
i:=1;
C[1]:='1';
except
C[1]:='0';
end;
fSocketStream.Write(c[1],1);
fSocketStream.Free;
except on e:exception do
begin
// Если произошла ошибка, то закрываем сокет и выходим
ClientSocket.Close;
Terminate;
end;
end;
finally
fSocketStream.Free;
end;
except on e:exception do
begin
// Если произошла ошибка, то закрываем сокет и выходим
ClientSocket.Close;
Terminate;
end;
end;
end;
end. |
|
0
|