Newsgroups : Borland : borland.public.delphi.internet.winsock : 2007 Dec : Re: idTcpClient and Streams
| Subject: | Re: idTcpClient and Streams |
| Posted by: | "Kendrick" (kkendri..@harbornet.com) |
| Date: | Wed, 5 Dec 2007 17:21:09 |
Remy - thank you - replies are spread thourgh the message - Kevin
"Remy Lebeau (TeamB)" <no.spam@no.spam.com> wrote in message
news:475739bc@newsgroups.borland.com...
>
> "Kendrick" <kkendrick@harbornet.com> wrote in message
> news:47572a37$1@newsgroups.borland.com...
>
>> Yes I am sure I am doing it all wrong - here are some snippets
>
> You did not show enough code to fully diagnose your problem.
>
>> #1 Server preps stream and sends size to client
>> aStream:= TMemoryStream.Create;
>> cds1.SaveToStream(aStream,dfBinary); // dfBinary, dfXML, dfXMLUTF8
>> SendClientMessage(aMsg, IntToStr(aStream.Size), False, True); //aMsg
>> has the IP address and client's thread handle
>
> What does SendClientMessage() actually do?
It parses the client.IP and client.Thread from aMsg and sends the message
IntToStr(aStream.Size) to the client. The other parameters control wheter a
log is written to and whether it is time stamped.
>
>> #2 Client builds request Command and sends to server:
>> tcp1.IOHandler.WriteLn('SENDDATA');
>> //aStream.Seek(0,0);
>> tcp1.IOHandler.ReadStream(aStream, (sizeOfServerStream)); //aStream is
>> TMemoryStream
>
> Where are you sending the original command that caused the server to
> prepare the data? Where are you reading that response to get the stream
> size? For that matter, why are you using separate commands to prepare the
> data and then receive it afterwards?
It is in another procedure. They will eventually be merged but this way I
can control the sequence of events and avoid (for the moment) timing issues.
>
>> #3 Server sends the stream
>> TIdContext(Cnncts[p]).Connection.IOHandler.WriteBufferOpen;
>> TIdContext(Cnncts[p]).Connection.IOHandler.Write(aStream);
>
> Are you ever calling WriteBufferClose()?
No - but what I have found:
I do not call writeBufferOpen at all but every read or write to
SavetoStream or LoadFromStream must be preceeded by aStream.position:= 0 to
reset the position to the begining.
>
> I do not recommend using write buffering with streams. Especially when
> large streams are involved. That wastes memory, and can cause socket
> errors anyway.
>
>> #4 Client gets the stream in OnWorkEnd
>
> Why are you loading the data from inside of OnWorkEnd instead of after
> ReadStream() exits?
Not sure - I have tried a lot of things. Now I have to step backwards.
OnWorkEnds does work - however - I changed to sending XML so that I can
view it easily on the client side. I am coming up 7 bytes short. Is there a
buried overhead that you know of. The size of the stream = 1983 bytes. If I
up it to 1990 I get a read timeout. It is consistant with every send.
>
>> Memo1.Lines.LoadFromStream(aStream); //This blanks out the Memo
>
> You are not seeking the stream's Position back to 0 after receiving the
> data before then loading it into the Memo.
Yep that is it!!!!
>
>> cds1.LoadFromStream(aStream); //cds1 is a clientdataset;
>
> Likewise, you are not seeing the Stream Position back to 0 after the Memo
> was loaded from it.
Yep that is it!!!!
>
>
> Gambit