Article View: borland.public.cppbuilder.internet.socket
Article #5085Re: How TServerSocket sends back data to TClientSocket... ?
From: Remy Lebeau (TeamB)
Date: Thu, 14 Oct 2004 16:42
Date: Thu, 14 Oct 2004 16:42
108 lines
4592 bytes
4592 bytes
"Vladimir Stefanovic" <spam@not.needed> wrote in message
news:416e8327@newsgroups.borland.com...
> InboxMemoryStream->Position = 0;
> char *Rec = new char[ InboxMemoryStream->Size + 1 ];
> InboxMemoryStream->ReadBuffer( Rec, InboxMemoryStream->Size );
> Rec[ InboxMemoryStream->Size ] = '\0';
You don't need to allocate a separate buffer. Just access the contents of
the TMemoryStream directly. You can use its Memory property to gain access
to the raw data.
> ...and want to send it back to client. How to send?
Stream->Write(YourData, YourDataSize);
> 1) Should I send data immediatelly, while I'm still in
> ClientExecute()?
Yes.
> 2) If yes, how can I address the client? Maybe the 'Stream->'
> pointer (I think that Mr Hans Galema said that once to me)?
Yes, use the existing TWinSocketStream.
> 3) Should I use the same concept of sening data like
> I did from the client side (piece by piece)?
Yes, because that is how TCP/IP works in general - data streams are
transmitted in blocks. When you send data, the writing function returns how
much data was actually written. Loop the writing until you have sent all of
the data in full. Then on the client side, loop the reading until all of
the data has been read in full.
> 4) On the clients side I suppose that I should use
> on OnRead(), what else?
Since you are using the client in non-blocking mode, then there isn't
anything else.
> 5) AFAIK, clients OnRead() is the common passage for all
> reads (it's not thread), so I have to be able to:
> - start receiving
> - extract 'sizeof_stream' when the received ammount of data
> exceeds sizeof(int)
> - continue reading while TOTAL_RECEIVED == sizeof_stream,
> then prepare for new reads
> - Clear-up if some error occure and prepare for new read
There is more involved than that. Since TCP transmits in blocks, and your
client is non-blocking, you are going to get multiple OnRead event triggers
while receiving the file stream. You have to code your client such that it
can handle multiple OnRead events, reading as little as 1 block per event,
and you have to exit the OnRead event periodically so that your whole
application is not fozen during the transfer.
> Does anyone have some similar code I should look at?
Try the following code instead:
__fastcall TclientForm::TclientForm(TComponent* Owner)
: TForm(Owner)
{
DataBuffer = new TMemoryStream;
expected_size = 0;
}
__fastcall TclientForm::~TclientForm()
{
delete DataBuffer;
}
void __fastcall TclientForm::ClientSocketRead(TObject *Sender,
TCustomWinSocket *Socket)
{
int IncomingSize = Socket->ReceiveLength();
if ( IncomingSize < 1 ) return;
int OldSize = DataBuffer->Size;
int NewSize = OldSize + IncomingSize;
DataBuffer->Size = NewSize;
Socket->ReceiveBuf( &((LPBYTE)(DataBuffer->Memory))[OldSize],
IncomingSize );
if( (DataBuffer->Position == 0) && (DataBuffer->Size >=
sizeof(int)) )
DataBuffer->Read( &expected_size, sizeof(int) );
if( (DataBuffer->Position == sizeof(int)) && ((DataBuffer->Size -
sizeof(int)) == expected_size) )
{
// process buffered data as needed...
DataBuffer->Clear();
expected_size = 0;
}
}
> Sometimes I think that it's easier to have alternative
> TClientSocket on server for sending and
> TServerSocket on client for receiving...
No. That just complicates your design. It is not necessary to do that.
Gambit
Technical Details
Message-ID:
<416eac69$1@newsgroups.borland.com>Path:
arc1-ca.pugleaf.net!g2news1.google.com!news1.google.com!news.glorb.com!npeer.de.kpn-eurorings.net!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mailReferences:
<416e8327@newsgroups.borland.com>Show Full Headers
Complete Article Headers
X-Google-Thread: 11508e,5efe1ef2e1363462 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: <416e8327@newsgroups.borland.com> Subject: Re: How TServerSocket sends back data to TClientSocket... ? Date: Thu, 14 Oct 2004 09:42:37 -0700 Lines: 110 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: <416eac69$1@newsgroups.borland.com> X-Trace: newsgroups.borland.com 1097772137 68.69.17.41 (14 Oct 2004 09:42:17 -0700) Path: arc1-ca.pugleaf.net!g2news1.google.com!news1.google.com!news.glorb.com!npeer.de.kpn-eurorings.net!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail