On Tue, 13 Mar 2001 05:05:40 -0500, "Don" <dsid...@charter.net> wrote:
>"John Dinning" <jdinn...@ozemail.com.au> wrote in message
>news:98kmcv$i1b1@bornews.inprise.com...
>> I have the same situation, and could only come up with the same solution -
>> ReadBuffer one byte at a time. I could see no other way and would also
>love
>> to hear of one.
>I don't know the specifics of the protocol you're creating, buy I'd
>recommend that it use some type of converstional style to know when things
>are going to happen. For instance, your client wants to send a JPG image
>stream of arbitrary length to the server. The conversation, after connect,
>might look like:
> C: SEND
> S: READY or ERR
> C: Write Stream Length
> C: Write Stream Data
> S: OK or ERR Data Stream Size
> ...
> C: QUIT
> S: DONE
>The client knowns that it initates all conversations, and must tell the
>server what to expect. The server knowns that it must handle incoming
>requests and generate both an ACK for the command and a response/result
>message.
>The client could write the stream length as a cardinal value for the server.
> try
> AClient.WriteLn('SEND');
> SResponse := AClient.ReadLn;
> if SResponse <> 'OK' then
> raise EMyProtocolServerError.Create(SResponse);
> // or whatever you need to do to handle a server error
> AStream.Position := 0;
> AClient.WriteCardindal(AStream.Size);
> AClient.WriteStream(AStream);
> SResponse := AClient.ReadLn;
> if SResponse <> 'OK' then
> raise EMyProtocolDataError.Create(SResponse);
> // or whatever you need to do to handle
> // a data error or lost connection
> finally
> ...
> end;
>The server could perform the converse in the OnExecute:
>with AThread.Connection do
>begin
> // say hello to the client
> while Connected do
> begin
> SCmd := ReadLn('', AServer.AcceptWait);
> if ReadLnTimedOut then
> begin
> // whatever you need to do to handle idle states
> end
> else if (SCmd = 'SEND') then
> begin
> WriteLn('READY');
> // or ERR if you can't receive
> iSize := ReadCardinal;
> ReadStream(AMemoryStream, iSize);
> if (AMemoryStream.Size <> iSize) then
> WriteLn('ERR Data stream size')
> else
> begin
> ProcessStream(AMemoryStream);
> WriteLn('OK');
> end;
> end
> else if SCmd = 'QUIT' then
> begin
> WriteLn('DONE');
> break;
> end;
> end;
> Disconnect;
>end;
>The command handling could be split up into individual methods, use numeric
>response codes, etc. But you get the idea. This avoids trying to make the
>blocking sockets behave like Async ones.
>hth...
>Don