🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

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

Re: Using TClientSocket &SendStream to transfer floats?

#4369
From: Remy Lebeau (TeamB)
Date: Tue, 15 Feb 2005 23:10
210 lines
6706 bytes
"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: <42128098$2@newsgroups.borland.com>
Path: arc1-ca.pugleaf.net!g2news1.google.com!news1.google.com!proxad.net!news.tele.dk!news.tele.dk!small.news.tele.dk!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail
References: <421275a3$1@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: "Remy Lebeau \(TeamB\)" <no.spam@no.spam.com>
Newsgroups: borland.public.cppbuilder.internet.socket
References: <421275a3$1@newsgroups.borland.com>
Subject: Re: Using TClientSocket &SendStream to transfer floats?
Date: Tue, 15 Feb 2005 15:10:43 -0800
Lines: 212
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 6.00.2800.1409
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1409
NNTP-Posting-Host: 68.69.17.41
Message-ID: <42128098$2@newsgroups.borland.com>
X-Trace: newsgroups.borland.com 1108508824 68.69.17.41 (15 Feb 2005 15:07:04 -0800)
Path: arc1-ca.pugleaf.net!g2news1.google.com!news1.google.com!proxad.net!news.tele.dk!news.tele.dk!small.news.tele.dk!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail