Article View: borland.public.cppbuilder.internet.socket
Article #4369Re: Using TClientSocket &SendStream to transfer floats?
From: Remy Lebeau (TeamB)
Date: Tue, 15 Feb 2005 23:10
Date: Tue, 15 Feb 2005 23:10
210 lines
6706 bytes
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-mailReferences:
<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