Newsgroups : Borland : borland.public.delphi.internet.winsock : 2008 Apr : TIdTCPServer and threads
| Subject: | TIdTCPServer and threads |
| Posted by: | "Mohammad" (mohamm..@programminghorizon.com) |
| Date: | Sun, 27 Apr 2008 18:35:17 +0330 |
I'm using TIdTCPServer in chat server application. since i migrated to Indy
i feel its more better and does not have most of problems that I had in
TServerSocket before. But still i experiencing some problems using Indy and
i have no idea if i'm doing some things wrong or there is bug(s) in
TIdTCPServer. I assigned TSchedulerof Thread Default to TIdTCPServer
Component also. After about 10 hours number of threads in Process grow up to
890 threads (i'm not sure but seems some threads not free after disconnect)
and I got
UserName:xxxxx IP: xx.xx.xxx.x Exception:Thread Error: The handle is
invalid (6)
UserName:xxxxxxxxxxxxx IP: xx.xxx.xxx.xxx Exception:Thread creation error:
Not enough storage is available to process this command
Exceptions in my OnExecute Event handler. Currently I have about 30 up to
300 users online at a time
Here is my Code for OnConnect, OnDisconnect and OnExecute Events:
procedure TMainForm.TCPServerConnect(AContext: TIdContext);
begin
AContext.Data := FUsers.Add(AContext);
end;
procedure TMainForm.TCPServerDisconnect(AContext: TIdContext);
begin
FUsers.Delete(AContext);
AContext.Data := nil;
end;
procedure TMainForm.TCPServerExecute(AContext: TIdContext);
begin
TUser(AContext.Data).ProcessBuffers;
end;
procedure TUser.ProcessBuffers;
var
Buffer: Pointer;
Buf: TBytes;
Len: Integer;
begin
Sleep(5);
FSocketLock.Enter;
try
Len := FContext.Connection.Socket.InputBuffer.Size;
if Len>0 then
begin
FContext.Connection.IOHandler.ReadBytes(Buf,Len);
GetMem(Buffer,Len);
CopyMemory(Buffer,@Buf[0],Len);
ProccesPacket(Buffer,Len);
FreeMem(Buffer);
end;
while OutputBufferList.Count>0 do
begin
Buffer := OutputBufferList.items[0];
Len := PCommunicatorPacket(Buffer).BufferSize;
SetLength(Buf,Len);
CopyMemory(@Buf[0],Buffer,Len);
FContext.Connection.IOHandler.Write(Buf);
FOutputCriticalSection.Enter;
OutputBufferList.Delete(0);
FOutputCriticalSection.Leave;
FreeMem(Buffer);
end;
try
// MilliSecondsBetween sometimes raise exception
// Invalid floatingpoint operation.
if (MilliSecondsBetween(Now,LastActivityTime)>20000) or
FDisconnectNeeded then
FContext.Connection.Disconnect(True); // is there any problem
calling disconnect from here(OnExecute)?
except
end;
except
on E: Exception do
MainForm.AddLog('UserName:'+UserName+' IP: '+IPAddress+'
Exception:'+E.Message,clRed);
end;
FSocketLock.Leave;
end;
in addtion some times i have the following exceptions too
UserName:xxxxxxx IP: xxx.x.xxx.xx Exception:Socket Error # 10053
Software caused connection abort.
UserName: IP: xx.xx.xxx.xx Exception:Item cannot be found in the
collection corresponding to the requested name or ordinal
UserName:xxxxxxxxxxxx IP: xx.xxx.xxx.xxx Exception:Operation cannot be
performed while executing asynchronously
Any suggestion for solving these problems????