🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

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

Re: Using TClientSocket &SendStream to transfer floats?

#4376
From: robertwf
Date: Thu, 17 Feb 2005 22:26
220 lines
7281 bytes
Remy,
Thanks for your help. I was able to implement one of your suggestions. By the way the Server for my Builder Client is a Matlab application. My current implementation is a little rough, but at least it works.
Thanks again for quick and informative support.

Robert

"Remy Lebeau \(TeamB\)" <no.spam@no.spam.com> wrote:
>
>"Robertwf" <robert.w.fuentes@lmco.com> wrote in message
>news:421275a3$1@newsgroups.borland.com...
>
>> I dont understand the use of the SaveToStream method:
>>      SaveToStream(TStream* Stream);
>
>You do not use SaveToStream() in this situation.
>
>> 1) create a TMemoryStream
>
>You do not need a TMemoryStream in this situation.  Just write the array
>directly to the socket.
>
>> AlgTech::Math::Matrix<double,2,2> test_float(1.0,2.0,3.0,4.0); //creates a
>2x2 array
>
>You did not show what the Matrix type looks like, or how it stores its
>internal data.  That makes a big difference on how the array data can be
>sent.  Assuming the Matrix is using a fixed-sized array (ie: arr[2][2]) such
>that the array memory is contigious, not containing pointers to multiple
>blocks of memory for each dimension, then you can try something like the
>following:
>
>    void foo()
>    {
>        AlgTech::Math::Matrix<double,2,2> test_float(1.0,2.0,3.0,4.0);
>
>        LPBYTE pBuf = (LPBYTE) &(test_float[0][0]);
>        int iSize = (sizeof(double)*4);
>
>        while( iSize > 0 )
>        {
>            int sent = ClientSocket1->Socket->SendBuf(pBuf, iSize);
>            if( sent < 0 )
>            {
>                if( WSAGetLastError() != WSAEWOULDBLOCK )
>                {
>                    // an error occured
>                    return;
>                }
>                Application->ProcessMessages();
>            }
>
>            else if( sent == 0 )
>                // socket disconnected
>
>            else
>            {
>                pBuf += sent;
>                iSize -= sent;
>            }
>        }
>    }
>
>
>Which can then be abstracted to the following:
>
>    bool SendData(TCustomWinSocket *Socket, void *Buffer, int BufSize)
>    {
>        LPBYTE pBuf = (LPBYTE) Buffer;
>
>        while( BufSize > 0 )
>        {
>            int sent = Socket->SendBuf(pBuf, BufSize);
>            if( sent < 0 )
>            {
>                if( WSAGetLastError() != WSAEWOULDBLOCK )
>                {
>                    // an error occured
>                    return false;
>                }
>                Application->ProcessMessages();
>                continue;
>            }
>
>            if( sent == 0 )
>            {
>                // socket disconnected
>                return false;
>            }
>
>            pBuf += sent;
>            BufSize -= sent;
>        }
>        return true;
>    }
>
>    void foo()
>    {
>        AlgTech::Math::Matrix<double,2,2> test_float(1.0,2.0,3.0,4.0);
>        int size = (sizeof(double) * 4);
>
>        if( SendData(ClientSocket1->Socket, &size, sizeof(size)) )
>            SendData(ClientSocket1->Socket, &(test_float[0][0]), size);
>    }
>
>
>A better way would be to send the floats individually, then it won't matter
>if the array memory is contiguous or not:
>
>    void foo()
>    {
>        AlgTech::Math::Matrix<double,2,2> test_float(1.0,2.0,3.0,4.0);
>
>        // so the receiver knows how many values to expect.
>        int count = 4;
>        if( SendData(ClientSocket1->Socket, &count, sizeof(int)) )
>        {
>            for(int x = 0; x < 2; ++x)
>            {
>                for(int y = 0; y < 2; ++y)
>                {
>                    if( SendData(ClientSocket1->Socket, &(test_float[x][y]),
>sizeof(double)) )
>                        return;
>                }
>            }
>        }
>    }
>
>
>Using the above, the receiver will read the values as a 1-dimension array.
>If you need to, you can send the dimension information as well so the
>receiver can reconstruct the original array as it was in the sender:
>
>    --- sender ---
>
>    void foo()
>    {
>        AlgTech::Math::Matrix<double,2,2> test_float(1.0,2.0,3.0,4.0);
>        int Dims = 2;
>        int Cols = 2;
>
>        if( SendData(ClientSocket1->Socket, &Dims, sizeof(int)) )
>        {
>            if( SendData(ClientSocket1->Socket, &Cols, sizeof(int)) )
>            {
>                for(int x = 0; x < 2; ++x)
>                {
>                    for(int y = 0; y < 2; ++y)
>                    {
>                        if( SendData(ClientSocket1->Socket,
>&(test_float[x][y]), sizeof(double)) )
>                            return;
>                    }
>                }
>            }
>        }
>    }
>
>
>    --- receiver ---
>
>    bool ReadData(TCustomWinSocket *Socket, void *Buffer, int BufSize)
>    {
>        LPBYTE pBuf = (LPBYTE) Buffer;
>
>        while( BufSize > 0 )
>        {
>            int read = Socket->ReceiveBuf(pBuf, BufSize);
>            if( read < 0 )
>            {
>                if( WSAGetLastError() != WSAEWOULDBLOCK )
>                {
>                    // an error occured
>                    return false;
>                }
>                Application->ProcessMessages();
>                continue;
>            }
>
>            if( read == 0 )
>            {
>                // socket disconnected
>                return false;
>            }
>
>            pBuf += read;
>            BufSize -= read;
>        }
>        return true;
>    }
>
>
>    {
>        double **arr = NULL;
>        int Dims = 0;
>        int Cols = 0;
>
>        if( ReadData(Socket, &Dims, sizeof(int)) )
>        {
>            if( ReadData(Socket, &Cols, sizeof(int)) )
>            {
>                std::vector< std::vector<double> >arr(Dims);
>                for(int x = 0; x < Dims; ++x)
>                {
>                    arr[x].resize(Cols);
>                    for(int y = 0; y < Cols; ++y)
>                    {
>                        if( ReadData(Socket, &(arr[x][y]), sizeof(double)) )
>                            return;
>                    }
>                }
>            }
>        }
>    }
>
>
>Gambit
>
>
Technical Details
Message-ID: <42151a33$1@newsgroups.borland.com>
Path: arc1-ca.pugleaf.net!g2news1.google.com!news4.google.com!news.glorb.com!newsfeed.icp.pl!news-out.newsgroups.com!propagator2-sterling.newsfeeds.com!news-in.newsfeeds.com!in.nntp.be!caladan.landsraad.net!newsgroups.borland.com!not-for-mail
References: <421275a3$1@newsgroups.borland.com> <42128098$2@newsgroups.borland.com>

Show Full Headers
Complete Article Headers
X-Google-Thread: 11508e,30e232a5d68591b8
X-Google-Attributes: gid11508e,public
X-Google-Language: ENGLISH,ASCII-7-bit
From: "robertwf" <robert.w.fuentes@lmco.com>
Sender: "robertwf" <robert.w.fuentes@lmco.com>
Reply-To: "robertwf" <robert.w.fuentes@lmco.com>
Subject: Re: Using TClientSocket &SendStream to transfer floats?
Newsgroups: borland.public.cppbuilder.internet.socket
X-User-Info: 192.91.147.34     
References: <421275a3$1@newsgroups.borland.com> <42128098$2@newsgroups.borland.com>
NNTP-Posting-Host: 207.105.83.66
Message-ID: <42151a33$1@newsgroups.borland.com>
Date: 17 Feb 2005 14:26:59 -0800
X-Trace: newsgroups.borland.com 1108679219 207.105.83.66 (17 Feb 2005 14:26:59 -0800)
Lines: 221
Path: arc1-ca.pugleaf.net!g2news1.google.com!news4.google.com!news.glorb.com!newsfeed.icp.pl!news-out.newsgroups.com!propagator2-sterling.newsfeeds.com!news-in.newsfeeds.com!in.nntp.be!caladan.landsraad.net!newsgroups.borland.com!not-for-mail