Newsgroups : Borland : borland.public.delphi.internet.winsock : 2007 Nov : Re: tidTCPClient/Server - problem transfering data.
| Subject: | Re: tidTCPClient/Server - problem transfering data. |
| Posted by: | "Arvid Haugen" (arv..@elis.no) |
| Date: | Thu, 22 Nov 2007 14:35:51 |
Thank you for a very good answer!!!
Actually the code that I implemented with an "End of message string" - looks
pretty much like your solution #2.
HOWEVER - I still check the InputBufferIsEmpty - so I assume this is the
problem after all.
My code looks like this (cut from the context - but I think you understand).
Do you think simply removing the check for
ElWebServiceClient.IdTCPClient[indeks].IOHandler.InputBufferIsEmpty will
solve my problem? It is a problem occuring once every 40000 messages or so -
so it is not easy to reproduce...
while not lEndBitOK do
begin
/// Check that buffer is not empty.
if not
ElWebServiceClient.IdTCPClient[indeks].IOHandler.InputBufferIsEmpty then
begin
lEbNo := 0;
/// Read data.
lData := ElWebServiceClient.IdTCPClient[indeks].IOHandler.ReadLn;
if trim(lData) = cElwinMessageEndBit then
lEndBitOk := true
else
begin
lParamListe.Add(lData)
end;
end
else /// Else if input buffer empty and it has been the last 1000
reads (10 seconds) - quit...
if lEbNo > 1000 then
begin
logg('Can not find ENDBIT ('+cElwinMessageEndBit+') in message,
giving up...', clogError);
break;
end
else
begin
logg('Endbit not found, waiting for data to be written.',
clogError);
lEbNo := lEbNo+1;
Sleep(10);
Application.ProcessMessages;
end;
Note: It is not stated in the documentation that this is an internal
function. Below is the content of the help documentation for
InputBufferIsEmpty for TidIOHandler:
"Indicates the input buffer for the IOHandler does not contain any data.
Pascal
function InputBufferIsEmpty: Boolean;
Returns
Boolean - True when the input buffer is empty.
Description
InputBufferIsEmpty is a Boolean function used to indicate if the InputBuffer
for the IOHandler contains any unhandled data.
InputBufferIsEmpty uses InputBuffer to determine if the buffer has been
assigned, and to get the existing length of the buffer.
Copyright © 1993-2006, Chad Z. Hower (aka Kudzu) and the Indy Pit Crew. All
rights reserved."
But I belive you when you say so - an will stop using that function :-)
I tried to implement solution #1 that you outlined, but this makes my client
hang - if I understand it correctly I will have to send the number of lines
sendt from the server so that the client know how many lines to read - or is
there some other way of doing it.
I changed that code to something like this to prevent the client from
hanging. Is this the correct way of doing it?
--- server ---
>
> procedure TForm5.IdTCPServer1Execute(AContext: TIdContext);
> //...
> begin
> // ...
> AContext.Connection.IOHandler.Write('201
> '+IntToStr(LLines.count -1));
> AContext.Connection.IOHandler.Write(LLines, True);
> // ...
> end;
>
> --- client ---
>
> var
> LLines: TStrings;
> begin
> Result := IdTCPClient1.SendCmd('100 Test', [201, 202]);
> if Result = 201 then
> begin LLines := TStringList.Create;
> try
> IdTCPClient1.IOHandler.ReadStrings(LLines,
> StrToInt(trim(IdTCPClient1.LastCmdResult.Text[0])));
> // loop through LLines as needed...
> finally
> LLines.Free;
> end;
> end;
> else
> //...
> end;
I will try out you other approaches too.
Thanks!
/Arvid.