Newsgroups : Borland : borland.public.delphi.internet.winsock : 2008 Apr : TIdTCPServer and threads

www.cryer.info
Managed Newsgroup Archive

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????

Replies:

www.cryer.info
Managed Newsgroup Archive