🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: borland.public.cppbuilder.internet.socket
5 messages
5 total messages Started by Raffaele Pantaleoni Mon, 06 Feb 2006 10:06
TCPServer Out of memory exception
#2681
Author: Raffaele Pantaleoni
Date: Mon, 06 Feb 2006 10:06
39 lines
2013 bytes
Hi to all,
I'm working with:
BCB 6 Enterprise (updated)
Windows XP Professional SP2 / Windows 2000 Professional
Indy 9.

I wrote two applications, a client and a server using Indy TCPClient and
 TCPServer.

During runtime I got on the Server OnExecute event an "Out of memory"
exception while trying to do a ReadLn, code follows.

void __fastcall TForm1::tcpServerExecute(TIdPeerThread *AThread)
{
  AnsiString Msg;
  //Get the text sent from the client
  try
  {
    Msg=AThread->Connection->ReadLn("",5);
  }
  catch (Exception &exception)
  {
    ExceptionsLog("tcpServerExecute",exception.Message);
  }
}

From time to time this error pops up. It takes several hours to come
out, more than six hours. Moreover it seems to come out when the channel
is idle (no communications between the client and the server).
The system memory is still avalaible when the error come out, and the
process itself hasn't growth in memory size.

All the tests were made on the same pc (address 127.0.0.1). The error
comes out either if I connect a telnet to my server or my client
application or both of them at the same time.

Any idea?
Thank you
Raffaele Pantaleoni
Re: TCPServer Out of memory exception
#2682
Author: Remy Lebeau (TeamB)
Date: Mon, 06 Feb 2006 22:03
38 lines
2549 bytes
Raffaele Pantaleoni <pantaraf@yahoo.it> wrote:

>    Msg=AThread->Connection->ReadLn("",5);

You did not specify any terminator.  Indy will use LF by default.  If the client sends lots of data without sending LF then you could be filling up memory.

Also, you specified a 5-millisecond timeout, but are not using the ReadLnTimedOut property afterwards.  Indy is best used when you let its operations block without timeouts, especially when using any of Indy's multithreaded components  Use timeouts only when you actually need to, and know how to handle them.

>  catch (Exception &exception)

If an Indy exception occurs (one that is derived from EIdException), you should re-throw the exception so that the server knows that something went wrong with the connection.  If you do not do that, or if you do not disconnect the connection manually, then the thread will never terminate properly.

For example:

    void __fastcall TForm1::tcpServerExecute(TIdPeerThread *AThread)
    {
        AnsiString Msg;
        try
        {
            Msg = AThread->Connection->ReadLn();
        }
        catch(const Exception &exception)
        {
            ExceptionsLog("tcpServerExecute", exception.Message);
            if( exception->InheritsFrom(__classid(EIdException)) )
                throw;
        }
    }

> The system memory is still avalaible when the error
> come out, and the process itself hasn't growth in
> memory size.

When the VCL runtime is allocating a string, a memory exception can be thrown without any actual memory actually being allocated if the runtime can determine ahead of time that the new string length is too large for memory to satisfy.


Gambit
Re: [SOLVED] TCPServer Out of memory exception
#2684
Author: Raffaele Pantaleoni
Date: Tue, 07 Feb 2006 08:12
31 lines
2590 bytes
Hi,
thak you for you answer.

Remy Lebeau (TeamB) ha scritto:
> Raffaele Pantaleoni <pantaraf@yahoo.it> wrote:
> 
>>    Msg=AThread->Connection->ReadLn("",5);
> 
> You did not specify any terminator.  Indy will use LF by default.  If the client sends lots of data without sending LF then you could be filling up memory.
I was aware about this, but when the error comes out nothing is coming
from the client, the link is idle. Moreover if the link is populated by
data, no errors come out.

>>  catch (Exception &exception)
> 
> If an Indy exception occurs (one that is derived from EIdException), you should re-throw the exception so that the server knows that something went wrong with the connection.  If you do not do that, or if you do not disconnect the connection manually, then the thread will never terminate properly.
Thank you for your complete answer. I intentionally cut out the rest of
my catch routine for easiness of reading, the rest of the catch routine
is about closing the connection and cleaning.

I think that I solved my problem, I raised the readln timeout up to 5000
and the server is running with an idle client connected for 15 hours
now. No "Out of memory" errors came out in the meantime. I will try also
a blocking readln, as you suggested.

I noticed that using a 1 ms timeout the "Out of memory" exception comes
out about every 5-8 minutes (using the very same conditions). While
using a 5 ms timeout it comes out in a range starting from 1 up to 3 hours.

Thank you.
Raffaele Pantaleoni
Re: TCPServer Out of memory exception
#2466
Author: Justin L Hudson
Date: Mon, 17 Apr 2006 15:14
54 lines
2922 bytes
I am having a similar issue using Borland 5, but I am using the server 
socket.  I can be sending the same data all day long using "SendText" then I 
get a error and wrapping a try and catch around it will not let go of it and 
the program closes?  My assumption at first was that AnsiString in SendText 
was bigger then what I could send?  But I am assumming since SendText 
returns the number of bytes sent I can send up to MaxInt of data?  But 
sometimes SendText will fail on shorter messages?  Any ideas on how to 
determine the root cause of SendText through memory exception?  Could I also 
set a timeout on the server socket?

Thanks,
Justin

"Raffaele Pantaleoni" <pantaraf@yahoo.it> wrote in message 
news:43e71eee$1@newsgroups.borland.com...
> Hi to all,
> I'm working with:
> BCB 6 Enterprise (updated)
> Windows XP Professional SP2 / Windows 2000 Professional
> Indy 9.
>
> I wrote two applications, a client and a server using Indy TCPClient and
> TCPServer.
>
> During runtime I got on the Server OnExecute event an "Out of memory"
> exception while trying to do a ReadLn, code follows.
>
> void __fastcall TForm1::tcpServerExecute(TIdPeerThread *AThread)
> {
>  AnsiString Msg;
>  //Get the text sent from the client
>  try
>  {
>    Msg=AThread->Connection->ReadLn("",5);
>  }
>  catch (Exception &exception)
>  {
>    ExceptionsLog("tcpServerExecute",exception.Message);
>  }
> }
>
> From time to time this error pops up. It takes several hours to come
> out, more than six hours. Moreover it seems to come out when the channel
> is idle (no communications between the client and the server).
> The system memory is still avalaible when the error come out, and the
> process itself hasn't growth in memory size.
>
> All the tests were made on the same pc (address 127.0.0.1). The error
> comes out either if I connect a telnet to my server or my client
> application or both of them at the same time.
>
> Any idea?
> Thank you
> Raffaele Pantaleoni 
Re: TCPServer Out of memory exception
#2469
Author: Remy Lebeau (TeamB)
Date: Mon, 17 Apr 2006 17:17
44 lines
2661 bytes
"Justin L Hudson" <justin.hudson@bepco.com> wrote in message
news:4443b0bc$1@newsgroups.borland.com...

> I am having a similar issue using Borland 5, but I am using the server
> socket.  I can be sending the same data all day long using "SendText"

SendText() is not an Indy method.  You cannot possibly be having a similar
issue that Raffaele was having using Indy.

> I get a error and wrapping a try and catch around it will not let go of
> it and the program closes?

That is highly unlikely.  Unless you are trying to catch a specific type of
exception that is not actually being thrown, and not catching the real one
that really is.  Please show your actual code.

> My assumption at first was that AnsiString in SendText was bigger
> then what I could send?

That assuption is wrong.  SendText() simply ignores whatever it cannot
accept, and returns a numeric value specifying how much it actually did
accept.  It is your responsibility to check that return value and then
re-call SendText() again if any of the string data was not accepted by the
socket.

> But I am assumming since SendText returns the number of bytes
> sent I can send up to MaxInt of data?

The socket will never allow that much data to be sent in a single operation.
That is way too much data for it to handle.  By default, the internal
buffers will only allow approx. 8Kb at a time.

I have also seen cases where the socket decided the application was trying
to send too much data in general and it would return an WSAENOBUFS error and
fail altogether.

> Any ideas on how to determine the root cause of SendText through
> memory exception?

There is no way to diagnose that without more details.


Gambit
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads