Article View: borland.public.cppbuilder.internet.socket
Article #251Re: Indy10 usage
From: Mike Ruskai
Date: Wed, 05 Mar 2008 22:52
Date: Wed, 05 Mar 2008 22:52
91 lines
4722 bytes
4722 bytes
On or about Tue, 4 Mar 2008 21:46:00 -0800 did "Remy Lebeau \(TeamB\)" <no.spam@no.spam.com> dribble thusly: > >"Mike Ruskai" <BUTthannydI@DONTearthlinkLIKE.netSPAM> wrote in message >news:ch7ss31acm13alsqj2s3utjhnbusnks1a9@4ax.com... > >> ReadBytes() throws an EIdConnClosedGracefully when the socket >> has been closed by the remote after all data had been sent. > >It should not be. The only time it should be raising that exception is if >you are trying to read more than was actually sent. Otherwise, ReadBytes() >should be returning the full requested data without raising an exception, >and then the next read/write operation will detect the disconnect >afterwards. Looking at the source, I do not see how that exception could be >occuring. > >> So, I have to do something like this to read all data: > >No, you should not have to do that. If what you describe is actually >happening (which, looking at the soure code, I don't see how it can), then >it is a bug that needs fixing. 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): 01) procedure TIdIOHandler.ReadBytes(var VBuffer: TIdBytes; AByteCount: 02) Integer; AAppend: Boolean = True); 03) begin 04) Assert(FInputBuffer<>nil); 05) if AByteCount > 0 then begin 06) // Read from stack until we have enough data 07) while FInputBuffer.Size < AByteCount do begin 08) ReadFromSource(False); 09) CheckForDisconnect(True, True); 10) end; 11) FInputBuffer.ExtractToBytes(VBuffer, AByteCount, AAppend); 12) end else if AByteCount < 0 then begin 13) ReadFromSource(False, ReadTimeout, False); 14) CheckForDisconnect(True, True); 15) FInputBuffer.ExtractToBytes(VBuffer, -1, AAppend); 16) end; 17) end; Here's the relevant bit in IdIOHandlerStack.pas: 01) procedure TIdIOHandlerStack.CheckForDisconnect( 02) ARaiseExceptionIfDisconnected: Boolean; AIgnoreBuffer: Boolean); 03) var 04) LDisconnected: Boolean; 05) begin 06) // ClosedGracefully // Server disconnected 07) // IOHandler = nil // Client disconnected 08) if ClosedGracefully then begin 09) if BindingAllocated then begin 10) Close; 11) // Call event handlers to inform the user that we were disconnected 12) DoStatus(hsDisconnected); 13) //DoOnDisconnected; 14) end; 15) LDisconnected := True; 16) end else begin 17) LDisconnected := not BindingAllocated; 18) end; 19) // Do not raise unless all data has been read by the user 20) if LDisconnected then begin 21) if (InputBufferIsEmpty or AIgnoreBuffer) and ARaiseExceptionIfDisconnected then begin 22) RaiseConnClosedGracefully; 23) end; 24) end; 25) end; Look at line 9 from the first snippet. It's calling CheckForDisconnect() with both arguments True. The first specifies that an exception should be raised when the socket is disconnected. The second specifies that data in the input buffer should be ignored, which would otherwise prevent the exception from being raised. And on line 21 of the second snippet, you see that it's throwing the exception, despite there being data in the buffer, because of the second option being True. The fix would be to change the second argument to CheckForDisconnect() to False, but I'm going to leave my workaround in place instead, at least until that bug is fixed in future snapshots. Perhaps you can add the fix to the codebase, since you're involved with the project?
Technical Details
Message-ID:
<c65us3ljh7nr89gl6i6sojfkumfuup7qrt@4ax.com>Path:
arc1-ca.pugleaf.net!g2news1.google.com!news3.google.com!news.germany.com!newsfeed01.sul.t-online.de!t-online.de!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>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 17:52:54 -0500 Message-ID: <c65us3ljh7nr89gl6i6sojfkumfuup7qrt@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> 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 1204757572 65.41.244.203 (5 Mar 2008 14:52:52 -0700) Lines: 91 Path: arc1-ca.pugleaf.net!g2news1.google.com!news3.google.com!news.germany.com!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail