Newsgroups : Borland : borland.public.delphi.internet.winsock : 2006 Jun : Re: IdTCPClient.Socket.Recv - Hangs
| Subject: | Re: IdTCPClient.Socket.Recv - Hangs |
| Posted by: | "brandon" (someo..@microsoft.com) |
| Date: | Wed, 21 Jun 2006 13:38:47 |
Key piece of info I missed was on the server side. The examples that I had
used, did not use any params on the WriteStream() except for the object.
This explains why I could only force the FileWrite on disconnect, which I
did not want to do...
Thanks for the Info... ;)
"Remy Lebeau (TeamB)" <no.spam@no.spam.com> wrote in message
news:44997ea0$1@newsgroups.borland.com...
>
> "brandon" <someone@microsoft.com> wrote in message
> news:44996c39@newsgroups.borland.com...
>
>> I am attempting to transfer a file with TidTCPClient and Server.
>>
>> I do not want to disconnect the client to indicate the file transfer
>> is complete, so I have the following code wich works...Mostly.
>
> You are doing it the wrong way. You should not be accessing the
> lower-level
> Socket methods directly at all. Use the higher-level Connection methods
> instead, such as WriteStream() and ReadStream(). For example:
>
> --- sending ---
>
> begin
> str := TFileStream.Create('c:\temp\tosend.jpg', fmOpenRead or
> fmShareDenyWrite);
> try
> AThread.Connection.WriteStream(str, True, True);
> finally
> FreeAndNil(str);
> end;
> end;
>
>
> --- receiving ---
>
> begin
> str := TFileStream.Create('c:\temp\rcvd.jpg', fmCreate);
> try
> IdTCPClient1.ReadStream(str);
> finally
> FreeAndNil(str);
> end;
> end;
>
>> The problem apears to be that when the last "chunk" of data is
>> read, if it is less than the SizeOfBuffer, the application hangs.
>
> That is because your code has no way of knowing when the end of file is
> actually received, so it tries to read an entire buffer that will never
> arrive. Remember that Indy is a blocking library. When you tell it to
> read
> a particular size of data, it waits for all of the requested data to
> arrive
> before continuing. It is not like Borland's non-blocking sockets where
> you
> can request a large buffer and it returns how much data was actually
> received if smaller. To do that, you would have to use the Connection's
> ReadFromStack() method instead, and check how the Size of the InputBuffer
> changes each time.
>
> Just use Read/WriteStream() instead, it does all of that for you. In the
> code I show above, the parameters of WriteStream() are telling it to send
> the stream's byte size before the actual data. The default parameters of
> ReadStream() tell it to expect that byte count to arrive so that it can
> know
> when to stop reading.
>
>> While the application is hung, the rcvd.jpg file size is 0.
>
> That is because the file stream is still open. The data has not been
> flushed to the hard drive yet.
>
>> Is there a timeout that needs to be set, or do I need to lay a
>> trap for EOF,...?
>
> You need to completely re-write your transferring code, since you are
> taking
> the wrong approach to begin with.
>
>
> Gambit
none