Article View: borland.public.cppbuilder.internet.socket
Article #4376Re: Using TClientSocket &SendStream to transfer floats?
From: robertwf
Date: Thu, 17 Feb 2005 22:26
Date: Thu, 17 Feb 2005 22:26
220 lines
7281 bytes
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-mailReferences:
<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