Добрый день!
Суть программы проста - клиент принимает некоторое количество данных, затем отправляет их на сервер, а сервер заносит их в базу данных.
Использую компоненты TServerSocket и TClientSocket. Сервер установил в stThreadBlocking, клиент соответственно в ctBlocking. Проблема в том, единовременный что запрос от одного клиента обрабатывается нормально, от двух тоже, а вот если одновременно подключаются 3 и более - то сервер отвергает все подключения (несмотря на то, что ThreadCacheSize = 20);
Код сервера:
Код:
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.
Юнит с потоком сервера:
Код:
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;
// ClientExecute отменяет
// TServerClientThread.ClientExecute
// и содержит код, который
// выполняется при старте потока
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
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.