Re: OutOfMemoryException from Thread.Start
- From: "Paul G. Tobey [eMVP]" <ptobey no spam AT no instrument no spam DOT com>
- Date: Mon, 18 Jul 2005 10:22:31 -0700
If the cable is unplugged before the message is acknowledged by the other
end, it should find out about it, because, once the time-outs expire, the
socket will go into an error state (TCP does this). If the cable is
unplugged after the sent packet is acknowledged, then the send was
successful and the next step in the process is where you'd want to find the
error.
If you're sitting there waiting for incoming data, you can have a problem.
That's what keep-alive is for. The default time-out for keep-alive isn't
too useful for real-time connect/disconnect, but you could change that via
the registry and set your socket for keep-alive. If you do that and the
cable is unplugged while you're waiting in a recv(), after the keep-alive
time-out, the socket will try to send a packet to the other end to verify
that it's still there. Since the cable is unplugged, that keep-alive packet
will not be acknowledged and the socket will go into the error state.
You can, without doing any resending on a single socket, get perfectly
reliable communications. Now, once the cable has been disconnected and that
disconnection detected, your programs might take that as a good chance to
close the socket (you'll never reestablish a connection through that socket,
once it's in the error state). If you *then* want to reestablish a
connection when the cable connection comes back and continue where you left
off, you might need to get resynchronized to get the process started up
again. You'd have to have the client reconnect, maybe send a tag, handle or
whatever you want to call it to tell the server that "I'm back", etc.
Anyway, this isn't the real problem, though; the exception is, so I'll drop
it.
Paul T.
"Michael--J" <MichaelJ@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
news:35D885F0-6A9F-44AD-B01A-8DC99BF2FC5B@xxxxxxxxxxxxxxxx
> Yes, i understand exactly what your trying to say and i've tried to
> portray
> the same argument to my supervisor. He however has tried to explain to me
> that what we are trying to accomplish (by resending) is reliability in the
> application layer. He understands the fact that TCP takes care of reliable
> transmission, but what happens when you send something and all of a sudden
> the enthernet cable gets unplugged? The higher level app will never know
> this
> - it will assume TCP has sent the data correctly, unless it performed
> another
> IO operation (i.e. a resend) which would trigger a SocketException. Having
> a
> resend mechanism ensures the application layer will always know whether or
> not a packet got sent or not.
>
> My supervisor emphasized the fact that other Application Layer protocols
> such as FTP also employ a resend mechanism.
>
> Thanks.
>
> "Paul G. Tobey [eMVP]" wrote:
>
>> I guess that what I'm saying is that you're implementing a resend
>> protocol
>> that, unless your code is written in a not-quite-right way will never be
>> executed. That is, *all* packets always get to the other end, because
>> TCP
>> guarantees it, and they always get there in the order they were sent, for
>> the same reason. If you *ever* retransmit, you're wasting network
>> resources
>> and there's no reason for it.
>>
>> Good luck with the exception!
>>
>> Paul T.
>>
>> "Michael--J" <MichaelJ@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
>> news:74D8DD8C-F7C1-474A-9B98-A97A6C910968@xxxxxxxxxxxxxxxx
>> > Hi Paul,
>> >
>> > Thanks for the swift reply. Please read inline:
>> >
>> > "Paul G. Tobey [eMVP]" wrote:
>> >
>> >> You don't have to implement your own resend process if you're using
>> >> stream/TCP sockets. That's all handled by the TCP layer of the
>> >> network
>> >> stack. In fact, by doing it yourself, you're quite likely to screw
>> >> things
>> >> up and get multiple copies of things at the other end. Also, your
>> >> algorithm
>> >> does *not* match TCP standards.
>> >>
>> >
>> > Yes i understand it doesn't match TCP standards... it's a protocol that
>> > runs
>> > above TCP. The reason why i decided to include a resend mechanism was
>> > because
>> > of the fact that the receiving end uses a fixed 2KB buffer to receive
>> > structures. Since the structures have varied lengths (ACK - 44bytes,
>> > DATA -
>> > 2048bytes), the receive process may receive an ACK and a DATA structure
>> > at
>> > the same receive() call and thus receives only 2048 bytes (the ACK and
>> > the
>> > first 2004 bytes of the DATA structure). The way the protocol has been
>> > implemented is that each structure has a unique signature to identify
>> > the
>> > start of the structure in the byte stream. Only structures with a
>> > correct
>> > sig
>> > will be processed. Thus in the example, the ACK will get processed but
>> > the
>> > DATA will not since i dont take care of incomplete packets. Thus the
>> > sending
>> > process will need to resend the structure and hope that the receiver
>> > will
>> > receive it in one 2KB chunk (i.e. in one call to receive()).
>> >
>> >> As for the out-of-memory, I'm not sure what might be going on, but you
>> >> should be sure that any previous threads that have been fired and are
>> >> done
>> >> properly exit. You might be running out of thread handles or
>> >> something
>> >> like
>> >> that, although that seems unlikely.
>> >>
>> >
>> > I see... I'm pretty sure the previous threads properly exit, but it's
>> > always
>> > hard to know things like that in the Compact Framework environment.
>> >
>> >> You might try asking the out-of-memory question in
>> >> microsoft.public.dotnet.framework.compactframework, as that's where
>> >> most
>> >> of
>> >> the managed code experts are located.
>> >>
>> >
>> > Ok Paul i will do that. Thanks very much for your help.
>> >
>> >> Paul T.
>> >>
>> >>
>> >> "Michael--J" <MichaelJ@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
>> >> news:D729402B-124B-434E-9325-9D5AE0E26F1F@xxxxxxxxxxxxxxxx
>> >> > Hi,
>> >> >
>> >> > I have an embedded board with a PXA 270 chip. It has a Win CE 5.0 OS
>> >> > image
>> >> > loaded and it supports CF v1. My task was to write a component which
>> >> > applications will use to transmit objects/structures to other
>> >> > application
>> >> > across the network. This component will be used by applications
>> >> > running
>> >> > on
>> >> > the board i mentioned above as well as in normal PC applications.
>> >> > This
>> >> > is
>> >> > the
>> >> > reason why i couldn't use .NET Remoting - CF does not support it.
>> >> > Consequently, i have written a component in C# which provides the
>> >> > following
>> >> > functions:
>> >> > - send a structure to a remote endpoint
>> >> > - receive a structure from a remote endpoint
>> >> >
>> >> > This is how i have implemented it:
>> >> > - On sending, the component serializes the object in wants to send
>> >> > into
>> >> > a
>> >> > stream of bytes (packet) first and then sends it by calling the
>> >> > Socket
>> >> > object's synchronous Send() method. Before returning, this send
>> >> > process
>> >> > needs
>> >> > to make sure that the other end received the packet (this is where
>> >> > the
>> >> > reliability part comes into the picture). To know that a packet was
>> >> > received
>> >> > correctly, the send process waits 200ms (RTO -
>> >> > ReTransmissionTimeout)
>> >> > for
>> >> > an
>> >> > ACK packet to come back (the reception of this ACK packet is
>> >> > explained
>> >> > below
>> >> > in the receive section**). If it doesn't receive an ACK by then, it
>> >> > resends
>> >> > the same packet. It continues to resend the packet every 200ms for
>> >> > 30
>> >> > secs.
>> >> > If it still hasn't received it by then, it disconnects the
>> >> > connection
>> >> > to
>> >> > the
>> >> > remote endpoint.
>> >> >
>> >> > - On receiving, bytes are received asynchronously by calling the
>> >> > Socket
>> >> > object's BeginReceive() and EndReceive() methods. The receiving
>> >> > process
>> >> > blocks until bytes become available on the receiving port. So when
>> >> > bytes
>> >> > do
>> >> > become available on the receiving port, they are read and
>> >> > deserialized
>> >> > back
>> >> > to the original object. In order not to miss any further incoming
>> >> > bytes,
>> >> > the
>> >> > currently received object is passed to another thread for
>> >> > processing.
>> >> > Hence
>> >> > the receiving process can return and call BeginReceive() again and
>> >> > wait
>> >> > for
>> >> > more bytes to come in.
>> >> > Now, the new thread that just got spawned will process the
>> >> > packet.
>> >> > This
>> >> > component is now being tested with a TestServerApplication (runs on
>> >> > my
>> >> > dev
>> >> > PC) and a
>> >> > TestClientApplication (runs on the PXA board). The server simply
>> >> > waits
>> >> > for
>> >> > clients to connect. When
>> >> > the client connects, the server accepts it and waits. The system was
>> >> > set
>> >> > up
>> >> > such that the client app sends a 2KB packet to the server and the
>> >> > server
>> >> > basically echoes it back. When the client receives the echo, it also
>> >> > echoes
>> >> > that back and so they play "packet tennis". This is simply to test
>> >> > the
>> >> > component. The size of an ACK packet is 44 bytes. So this is what
>> >> > happens:
>> >> >
>> >> > - client sends 2KB to server
>> >> > - server receives and sends a 44-byte ACK, and then the echo 2KB
>> >> > packet
>> >> > to
>> >> > the client
>> >> > - client receives the ACK (which ends the first send), and then also
>> >> > receives the echoed packet... client then sends an ACK to the
>> >> > server,
>> >> > as
>> >> > well
>> >> > as the echo packet
>> >> > - and the process repeats...
>> >> >
>> >> > Now, the problem i am having occurs on the PXA side. At some random
>> >> > point
>> >> > in
>> >> > time, when a structure is received and it is passed to another
>> >> > thread
>> >> > for
>> >> > processing, an OutOfMemoryException occurs when calling
>> >> > Thread.Start().
>> >> > So
>> >> > i
>> >> > thought, ok maybe there isn't much RAM, but then i ran it again with
>> >> > the
>> >> > RAM
>> >> > settings opened (the Control Panel item showing how much Storage
>> >> > Memory
>> >> > and
>> >> > Program Memory the system has). While the app runs, the amount of
>> >> > RAM
>> >> > decreases but when the exception occurs, there seems to be a few MBs
>> >> > left
>> >> > of
>> >> > program memory... how could this exception have been raised?
>> >> > Thanks...
>> >> >
>> >> > I have written a client application in C# The board will be used to
>> >> > run
>> >> > a
>> >> > client application which will connect
>> >>
>> >>
>> >>
>>
>>
>>
.
- Follow-Ups:
- Re: OutOfMemoryException from Thread.Start
- From: Michael--J
- Re: OutOfMemoryException from Thread.Start
- References:
- OutOfMemoryException from Thread.Start
- From: Michael--J
- Re: OutOfMemoryException from Thread.Start
- From: Paul G. Tobey [eMVP]
- Re: OutOfMemoryException from Thread.Start
- From: Michael--J
- Re: OutOfMemoryException from Thread.Start
- From: Paul G. Tobey [eMVP]
- Re: OutOfMemoryException from Thread.Start
- From: Michael--J
- OutOfMemoryException from Thread.Start
- Prev by Date: Selecting Audio Device
- Next by Date: Re: Help me!About Win CE .net Registry
- Previous by thread: Re: OutOfMemoryException from Thread.Start
- Next by thread: Re: OutOfMemoryException from Thread.Start
- Index(es):
Relevant Pages
|