Article View: borland.public.cppbuilder.internet.socket
Article #2889Re: Non-blocking socket - how to detect when server has finished writing to client
From: Mark Jacobs
Date: Wed, 04 Jan 2006 12:12
Date: Wed, 04 Jan 2006 12:12
119 lines
5592 bytes
5592 bytes
Vladimir Stefanovic wrote:
> Hi Mark,
>
>
>>[...] the reply to all POP3 commands is either very short, or multi-line
>>and terminated with a line starting with a full stop. In the long requests
>>like
>>RETR and TOP x y, I stop waiting to read any more when I get this line
>>in my buffer.
>
>
> Yes you must know the rules (protocol) to finalize you block of received
> data.
> if "AnsiString(bf).Pos("\r\n.")>0" is the rule, than OK.
>
>
>>[...] Also, is 2048 a good read value to use?
>
>
> Yes it is, but you *must not* count on that.
>
> I already posted for you in attachments group the whole
> TClientSocket/TServerSocket
> code, which has all elements of ctNonBlocking / stBlocking architecture.
>
> This is PSEUDO, code, what you have to do:
>
> void __fastcall TClientForm::AskClientSocketRead(TObject *Sender,
> TCustomWinSocket *Socket)
> {
> // read the incoming size of data that are passed to client...
> int IncomingSize = Socket->ReceiveLength();
>
> // if its less than zero, feel free to return and wait for another try...
> if ( IncomingSize < 1 )
> return;
>
> // calculate the LAST size of your data buffer where you store the
> portions...
> // ... sent to client to finalize one logical block of data...
> int OldSize = DataBuffer->Size;
>
> // set the new position where the new reading start...
> DataBuffer->Position = OldSize;
>
> // calculate the NEW size of DataBuffer
> int NewSize = OldSize + IncomingSize;
>
> // set the new size of the buffer, so that we can work with allocated
> buffer
> DataBuffer->Size = NewSize;
>
> // this will read the sent data into DataBuffer
> Socket->ReceiveBuf( &((LPBYTE)(DataBuffer->Memory))[OldSize],
> IncomingSize );
>
> // now, check if it's the end of header...
> if ( /* somethng with Pos("\r\n.") on dataBuffer* / )
> {
> // if yes, then:
> // 1) place the DataBuffer in your Grid
> // 2) reset the DataBuffer's Size & Position
> // DataBuffer->Size = NewSize;
> // DataBuffer->Position = 0;
> }
>
> }
>
> ...and this is DataBuffer:
>
> //---------------------------------------------------------------------------
> __fastcall TClientForm::TClientForm(TComponent* Owner)
> : TForm(Owner)
> {
> DataBuffer = new TMemoryStream();
> DataBuffer->Clear();
> DataBuffer->Position = 0;
> }
> __fastcall TClientForm::~TClientForm()
> {
> delete DataBuffer;
> }
>
> Look at my code in attachemnts group.
>
> Also you may look at the generic code for all sending amd receiving of
> Remy Lebeau, which is placed many times before in this group:
> http://tinyurl.com/dkbe9
>
> Happy New Year
>
Thanks Vladimir. I discovered that putting Sleep in the OnClientRead routine is a calamity
waiting to happen. When comms locks up, so does the app! I have now got it perfect. And I
understand exactly what is happening and why. My code now looks like this :-
//---------------------------------------------------------------------------
void __fastcall TForm1::ClientSocket1Read(TObject *Sender,TCustomWinSocket *Socket)
{
int ii=Socket->ReceiveLength();
ii=Socket->ReceiveBuf(&bf[wh],ii); wh+=ii; bf[wh]='\0';
dun=(!needot || AnsiString(bf).Pos("\r\n.\r\n")>0);
}
//---------------------------------------------------------------------------
I also found that sending a NOOP to the server every second, whilst waiting for the data
to be sent, stops the server "forgetting about you" and closing the connection. I now have
a superb bulk email handling program, which deals with my 10,000 spam emails a day
problem, and allows me to fine tune spam filters and whitelists. It's a bit like JBMail in
look, but JBMail tries to do too much IMO, and charges you for the full version. I may
make this offering free on my website, like MJ Registry Watcher. Keep your eyes peeled for
new additions to my free software page at http://www.jacobsm.com/mjsoft.htm
Now, back to my question about a VCL component that is free of charge, and understands how
to decode the attachments out of a text file returned by a POP3 call to RETR.
--
Mark Jacobs
http://www.dkcomputing.co.uk
Technical Details
Message-ID:
<43bbbb1a@newsgroups.borland.com>Path:
arc1-ca.pugleaf.net!g2news1.google.com!news1.google.com!news4.google.com!border1.nntp.dca.giganews.com!border2.nntp.dca.giganews.com!nntp.giganews.com!novia!nx01.iad01.newshosting.com!newshosting.com!news-out.newsfeeds.com!propagator2-sterling.newsfeeds.com!in.nntp.be!caladan.landsraad.net!newsgroups.borland.com!not-for-mailReferences:
<43b66ea8@newsgroups.borland.com> <43b6bd83@newsgroups.borland.com> <43b70dbb$1@newsgroups.borland.com> <43b7878e@newsgroups.borland.com>Show Full Headers
Complete Article Headers
X-Google-Thread: 11508e,e5c1e8b6c618095e X-Google-Attributes: gid11508e,public X-Google-Language: ENGLISH,ASCII-7-bit Date: Wed, 04 Jan 2006 12:12:23 +0000 From: Mark Jacobs <http://www.jacobsm.com/mjmsg.htm?mj@critical> User-Agent: Mozilla Thunderbird 1.0.6 (Windows/20050716) X-Accept-Language: en-us, en MIME-Version: 1.0 Newsgroups: borland.public.cppbuilder.internet.socket Subject: Re: Non-blocking socket - how to detect when server has finished writing to client References: <43b66ea8@newsgroups.borland.com> <43b6bd83@newsgroups.borland.com> <43b70dbb$1@newsgroups.borland.com> <43b7878e@newsgroups.borland.com> In-Reply-To: <43b7878e@newsgroups.borland.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit NNTP-Posting-Host: 81.144.157.8 Message-ID: <43bbbb1a@newsgroups.borland.com> X-Trace: newsgroups.borland.com 1136376602 81.144.157.8 (4 Jan 2006 04:10:02 -0700) Lines: 119 Path: arc1-ca.pugleaf.net!g2news1.google.com!news1.google.com!news4.google.com!border1.nntp.dca.giganews.com!border2.nntp.dca.giganews.com!nntp.giganews.com!novia!nx01.iad01.newshosting.com!newshosting.com!news-out.newsfeeds.com!propagator2-sterling.newsfeeds.com!in.nntp.be!caladan.landsraad.net!newsgroups.borland.com!not-for-mail