🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: borland.public.cppbuilder.internet.socket
Article #2894

Re: TWinSocketStream Read in BYTE buffer

#2894
From: Maurice Anderson
Date: Thu, 05 Jan 2006 10:04
154 lines
6552 bytes
Also found an issue in ReadBuf which causes TFileStream *FS to write fewer
bytes to the file than what is in the stream.  For example:

(1)  We have a file that is hdrfx1.jpg(63,820) bytes sent from the client

http://www.sonystyle.com/intershoproot/eCS/Store/en/imagesProducts/650x650/H
DRFX1.jpg

(2)  When it hits my server it first goes to ReadPacket(..)
       where it is determined to be a file.
(3)  From there it gets sent to ReadFile(..).
(4)  ReadFile calls Readbuf in a while loop to read the contents
      from the stream into a buffer 256 bytes at a time

          TFileStream *FS = new TFileStream(fn, fmCreate);
          .....
        BYTE rbuf[256];
          .....
                        while( size > 0 )
                        {
                            bufsize = size;
                            if( bufsize > sizeof(rbuf) )
                                bufsize = sizeof(rbuf);

                            if( !ReadBuf(rbuf, bufsize) )
                            {
                                error = true;
                                break;
                            }

                            if( FS->Write(rbuf, bufsize) < 1 )
                            {

(5)  So ReadBuf is called 249 times to read 63,744 Bytes.
       And each time ReadBuf returns, FS faithfully writes the contents
       to itself the same 249 times.  This leaves the last 76 Bytes to go.

(6)  All is good so far until we have to read the last 76 Bytes
       to complete the file.  For this we have to take a look
       at ReadBuf.

bool __fastcall ReadBuf(TWinSocketStream *Stream, void *Buffer, int
BufSize)
    {
        BYTE *pBuf = (BYTE*) Buffer;
        int NumRead;

        while( BufSize > 0 )
        {
            NumRead = Stream->Read(pBuf, BufSize);
            if( NumRead < 1 )
                return false;

            pBuf += NumRead;
            BufSize -= NumRead;
        }

        return true;
    }

(7) You see, once the Stream reads those 76 Bytes into pBuf, it cycles
      back once more.  On this last cycle in encounters 0 bytes to read
      so it kicks back a false as the return variable:

                    if( NumRead < 1 )
                    return false;

(8)  The false return goes back to ReadFile where it gets completely kicked
       out of the while loop before those last 76 Bytes are read by FS.

                            if( !ReadBuf(rbuf, bufsize) )
                            {
                                error = true;
                                break;         < - exists loop with 76 bytes
left in rBuf
                            }

                            if( FS->Write(rbuf, bufsize) < 1 ) <- Never sees
the last 76 bytes
                            {

(9)  So we end up with a file written short those 76 Bytes.

(10)  To resolve this I change around ReadBuf to return the number of
         bytes read.  If the bytes read from ReadBuf are < 1, then I kick
out
         of the while loop.

         Therefore, FS gets to read those last 76 Bytes before the while
loop
         is exited and we have our complete file transferred.

int __fastcall TBinaryTransfer::ReadBuf(TStream *Stream, void *Buffer,
    int BufSize)
{
        BYTE *pBuf = (BYTE*) Buffer;
        int NumRead;
        int NumRead2 = 0;
        try
        {
            while( BufSize > 0 )
            {
                NumRead = Stream->Read(pBuf, BufSize);
                if( NumRead < 1 ){

                    return NumRead2;
                }
                NumRead2 = NumRead; <- Holds the last byte amount read
                                                            in case we have
to return when we hit zero.
                pBuf += NumRead;
                BufSize -= NumRead;
            }
        }
        catch(const Exception &)
        {
            return 0;
        }

        return 256;
}

ReadFile:
                while( size > 0 )
                {
                            if( bufsize > sizeof(rbuf) )
                                bufsize = sizeof(rbuf);

                            numread = ReadBuf(Stream, rbuf, bufsize, 0);

                            if( numread < 1 )
                            {
                                error = true;
                                break;              <-- exits only when we
are sure there
                                                              is nothing
left in rbuf
                            }

                            if( FS->Write(rbuf, numread) < 1 )
                            {
                                error = true;
                                break;
                            }

                            size -= bufsize;
                }

Thanks again, you are a life saver.......... troubleshooting the code help
me really understood how you read and processed the contents of the stream.
You are truly very talented in this area and a blessing to many people.  And
your insights are always appreciated.

-M-
Technical Details
Message-ID: <43bcedb2$1@newsgroups.borland.com>
Path: arc1-ca.pugleaf.net!g2news1.google.com!news1.google.com!news3.google.com!border1.nntp.dca.giganews.com!nntp.giganews.com!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
References: <43ac3d34$1@newsgroups.borland.com> <43ac6028$1@newsgroups.borland.com> <43acc4c5$1@newsgroups.borland.com> <43ae5b51$1@newsgroups.borland.com> <43aeebe1$1@newsgroups.borland.com> <43aef70e$1@newsgroups.borland.com> <43af06d7$1@newsgroups.borland.com> <43b252fa$1@newsgroups.borland.com> <43b43a5a$1@newsgroups.borland.com> <43b45550$1@newsgroups.borland.com> <43b5a868$1@newsgroups.borland.com> <43b9b1b0$2@newsgroups.borland.com>

Show Full Headers
Complete Article Headers
X-Google-Thread: 11508e,74cdc31c66b3abd9
X-Google-Attributes: gid11508e,public
X-Google-Language: ENGLISH,ASCII-7-bit
From: "Maurice Anderson" <mauriceanderson@hotmail.com>
Newsgroups: borland.public.cppbuilder.internet.socket
References: <43ac3d34$1@newsgroups.borland.com> <43ac6028$1@newsgroups.borland.com> <43acc4c5$1@newsgroups.borland.com> <43ae5b51$1@newsgroups.borland.com> <43aeebe1$1@newsgroups.borland.com> <43aef70e$1@newsgroups.borland.com> <43af06d7$1@newsgroups.borland.com> <43b252fa$1@newsgroups.borland.com> <43b43a5a$1@newsgroups.borland.com> <43b45550$1@newsgroups.borland.com> <43b5a868$1@newsgroups.borland.com> <43b9b1b0$2@newsgroups.borland.com>
Subject: Re: TWinSocketStream Read in BYTE buffer
Date: Thu, 5 Jan 2006 02:04:53 -0800
Lines: 156
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 6.00.2800.1106
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1106
NNTP-Posting-Host: 64.30.203.223
Message-ID: <43bcedb2$1@newsgroups.borland.com>
X-Trace: newsgroups.borland.com 1136455090 64.30.203.223 (5 Jan 2006 01:58:10 -0700)
Path: arc1-ca.pugleaf.net!g2news1.google.com!news1.google.com!news3.google.com!border1.nntp.dca.giganews.com!nntp.giganews.com!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