Article View: borland.public.cppbuilder.internet.socket
Article #255Re: Indy10 usage
From: Mike Ruskai
Date: Thu, 06 Mar 2008 04:11
Date: Thu, 06 Mar 2008 04:11
72 lines
4963 bytes
4963 bytes
On or about Wed, 5 Mar 2008 16:36:20 -0800 did "Remy Lebeau \(TeamB\)" <no.spam@no.spam.com> dribble thusly: > >"Mike Ruskai" <BUTthannydI@DONTearthlinkLIKE.netSPAM> wrote in message >news:c65us3ljh7nr89gl6i6sojfkumfuup7qrt@4ax.com... > >> Sometimes I forget I have code available to check. I checked >> the code, and I see exactly how this is happening. >> >> Here's the relevant bit in IdIOHandler.pas (lines numbered for reference): ><snip> > >Your analysis, although technically accurate, is misplaced in this >situation. [snip] >Think about it. The server sends 1024 bytes and then disconnects. Your >client calls ReadBytes(..., 1024). ReadBytes(), seeing that the InputBuffer >does not hold enough bytes yet, calls ReadFromSource(). 1 of 3 things will >happen: > >1) at least 1 byte will be read from the socket. All of the received bytes >will be stored in the InputBuffer, ReadFromSource() will exit without >setting the ClosedGracefully property to True, CheckForDisconnect() will >exit without error, and ReadBytes() will check the InputBuffer again. If >needed, the cycle continues for another iteration. > >2) no bytes are received. This means the socket reported a disconnect >before all of the expected bytes could be read. ReadFromSource() will set >the ClosedGracefully property to True and exit. CheckForDisconnect() will >see that the ClosedGracefully property is True and raise an exception. >ReadBytes() was expecting 1024 bytes, but only received (1024-X) bytes. The >socket has already discarded the remaining bytes. There is nothing Indy can >do about that. Raising an exception is the proper behavior. > >3) the socket reports an actual error. An exception will be raised >accordingly. > >So, given the example you have shown earlier, the only way an >EIdConnClosedGracefully exception can be raised is if the socket itself is >actually reporting a disconnect before all of the expected bytes could be >read from it. If you are seeing ReadBytes() raise an exception too early in >your code, then that is the only thing that can be happening. The only >reason to catch the exception and call ExtractToBytes() manually would be if >you don't care that a disconnect was reported prematurely and want to >continue processing whatever data was successfully buffered beforehand. >Which, in most cases, will fail anyway since the data is incomplete and will >likely break whatever protocol you are implementing. I don't have the time to dig in and check everything above, but your conclusion is quite incorrect. The entire amount of data was sent over the socket, and received into the input buffer. The problem is that ReadBytes() fails to check the input buffer if there's no more data to read directly from the socket. So it throws the exception, which leaves no recourse but to read from the buffer directly for the last bit of data that was sent. If that is part of the design, the design is flawed. But I said that from the start - ReadBytes() wants to block until it gets the total requested bytes, when a proper function of the sort would read UP TO that number of bytes, returning anywhere from 0 to the requested number. Or at the least, it would only block until it receives at least 1 byte. As it is, the function is documented as either waiting until that number of bytes is read, or until the socket is disconnected. But when the socket is disconnected, it's not retrieving the last bytes from the buffer, necessitating the workaround I used. If you can show "proper" usage of ReadBytes() that doesn't require going to the buffer for the last bit of data, I'm all eyes.
Technical Details
Message-ID:
<n9rus3198r3a36l12l301alsg8o2s7q11i@4ax.com>Path:
arc1-ca.pugleaf.net!g2news1.google.com!news1.google.com!border1.nntp.dca.giganews.com!nntp.giganews.com!nx01.iad01.newshosting.com!newshosting.com!203.109.252.33.MISMATCH!newsfeeds.ihug.co.nz!ihug.co.nz!newsgroups.borland.com!not-for-mailReferences:
<ghsqs35tipni65rjlntjpl7hgi6f1bv1g8@4ax.com> <47cd89bb$1@newsgroups.borland.com> <tefrs3lpnfkk0arr2qa3vospikaj3j491h@4ax.com> <47cdc920@newsgroups.borland.com> <tu0ss39uaq8j35if50r88eflpsf5nvs431@4ax.com> <ch7ss31acm13alsqj2s3utjhnbusnks1a9@4ax.com> <47ce339a$1@newsgroups.borland.com> <c65us3ljh7nr89gl6i6sojfkumfuup7qrt@4ax.com> <47cf3c78@newsgroups.borland.com>Show Full Headers
Complete Article Headers
X-Google-Thread: 11508e,ea086d952e8cb041 X-Google-Attributes: gid11508e,public,usenet X-Google-Language: ENGLISH,ASCII-7-bit From: Mike Ruskai <BUTthannydI@DONTearthlinkLIKE.netSPAM> Newsgroups: borland.public.cppbuilder.internet.socket Subject: Re: Indy10 usage Date: Wed, 05 Mar 2008 23:11:02 -0500 Message-ID: <n9rus3198r3a36l12l301alsg8o2s7q11i@4ax.com> References: <ghsqs35tipni65rjlntjpl7hgi6f1bv1g8@4ax.com> <47cd89bb$1@newsgroups.borland.com> <tefrs3lpnfkk0arr2qa3vospikaj3j491h@4ax.com> <47cdc920@newsgroups.borland.com> <tu0ss39uaq8j35if50r88eflpsf5nvs431@4ax.com> <ch7ss31acm13alsqj2s3utjhnbusnks1a9@4ax.com> <47ce339a$1@newsgroups.borland.com> <c65us3ljh7nr89gl6i6sojfkumfuup7qrt@4ax.com> <47cf3c78@newsgroups.borland.com> X-Newsreader: Forte Agent 4.2/32.1118 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit NNTP-Posting-Host: 65.41.244.203 X-Trace: newsgroups.borland.com 1204776658 65.41.244.203 (5 Mar 2008 20:10:58 -0700) Lines: 72 Path: arc1-ca.pugleaf.net!g2news1.google.com!news1.google.com!border1.nntp.dca.giganews.com!nntp.giganews.com!nx01.iad01.newshosting.com!newshosting.com!203.109.252.33.MISMATCH!newsfeeds.ihug.co.nz!ihug.co.nz!newsgroups.borland.com!not-for-mail