BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Help using sockets.....
Goto page 1, 2  Next
 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> C++ Builder (Internet Socket)
View previous topic :: View next topic  
Author Message
Paul
Guest





PostPosted: Wed Apr 06, 2005 7:00 am    Post subject: Help using sockets..... Reply with quote



I'm getting an error trying to access this hyperlink :
http://bdn.borland.com/article/0,1410,26276,00.html


"Hans Galema" wrote in message news:42524093$1 (AT) newsgroups (DOT) borland.com...
Quote:
Paul wrote:
I'm trying to understand using sockets in BCB6, and after days of trying
out
different things I'm no further than when I started. I've looked at the
"chat" example and can following the blocking mechanism.

Well that is non-blocking.

However, the "chat" example sends text, not binary. And doesn't use non
blocking thread (or any threads). I've looked at the BCB help, and
there
are so many classes I'm completely confused as to what can and can't be
used
in run time.

It can be easy changed to send binary. You can find many
examples in borland.public.cppbuilder.internet.socket
Have a look there for complete examples for sending
and receiving.

You can find the basics for a threaded socket server here:
http://bdn.borland.com/article/0,1410,26276,00.html

If you have questions please post them in the sockets newsgroup.

Hans.



Back to top
Hans Galema
Guest





PostPosted: Wed Apr 06, 2005 7:57 am    Post subject: Re: Help using sockets..... Reply with quote



Paul wrote:
Quote:
I'm getting an error trying to access this hyperlink :
http://bdn.borland.com/article/0,1410,26276,00.html

Then try again. I got the error too. But after some
minutes it worked again.

Hans.

Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Wed Apr 06, 2005 8:00 am    Post subject: Re: Help using sockets..... Reply with quote




"Paul" <plmacca (AT) clara (DOT) co.uk> wrote

Quote:
I'm getting an error trying to access this hyperlink :
http://bdn.borland.com/article/0,1410,26276,00.html

Works fine for me.


Gambit



Back to top
Paul
Guest





PostPosted: Wed Apr 06, 2005 4:04 pm    Post subject: Re: Help using sockets..... Reply with quote

Works for me now too. I'll give this a go and see if it works any
differently to the one I've been trying to do, and then see what the
differences are if it works.

Questions:

1) This comment in the tutorial seems to imply the approach isn't to drag
and drop a component....

// Instead of using a client socket component that you place in your
application
// from the Component palette, the server client thread must use the
TServerClientWinSocket
// object that is created when the listening server socket accepts a client
connection.

2) All the examples of using sockets in BCB seem to be based around the
component pallete and using the main VCL thread. Are there classes for
sockets that can be used in threads without interacting with the main VCL
thread at all?

Off to try the example

Paul


"Hans Galema" <notused (AT) notused (DOT) nl> wrote

Quote:
Paul wrote:
I'm getting an error trying to access this hyperlink :
http://bdn.borland.com/article/0,1410,26276,00.html

Then try again. I got the error too. But after some
minutes it worked again.

Hans.



Back to top
Paul
Guest





PostPosted: Wed Apr 06, 2005 5:48 pm    Post subject: Re: Help using sockets..... Reply with quote

Right. I've tried the tutorial and I get the same problem. Every time the
server gets data it drops into the client socket close(), snippet below,
which is in the TMyServerThread.

if (pStream->Read(buffer, sizeof(buffer)) == 0)
// (if can't read in 60 seconds) than close the connection
ClientSocket->Close();

Can I confirm:
The client app component (drag + drop onto the form) is "ctNonBlocking"?
The server app component (drag + drop onto the form) is "stThreadBlocking"
and has an event handler for get thread.

//--------------------------------------------------------------------------
-
void __fastcall TForm1::ServerSocket1GetThread(TObject *Sender,
TServerClientWinSocket *ClientSocket, TServerClientThread
*&SocketThread)
{
SocketThread = new TMyServerThread(false, ClientSocket);
}
void __fastcall TForm1::SocketOpenClick(TObject *Sender)
{
// open thread blocking socket
ServerSocket1->Active = true;
}
void __fastcall TForm1::SocketCloseClick(TObject *Sender)
{
// close thread blocking socket
ServerSocket1->Active = false;
}


Back to top
Hans Galema
Guest





PostPosted: Wed Apr 06, 2005 6:00 pm    Post subject: Re: Help using sockets..... Reply with quote

Paul wrote:
Quote:
Right. I've tried the tutorial and I get the same problem.

Which problem ?

Quote:
Every time the
server gets data it drops into the client socket close(), snippet below,
which is in the TMyServerThread.

if (pStream->Read(buffer, sizeof(buffer)) == 0)
// (if can't read in 60 seconds) than close the connection
ClientSocket->Close();

Well it should only close after 60 seconds. Can you confirm that ?
And .. If you do not want to close then don't.

Quote:
Can I confirm:
The client app component (drag + drop onto the form) is "ctNonBlocking"?

Pleas use the right names. You mean: The TClientSocket in this example
if of type ctNonBlocking ? yes.

Quote:
The server app component (drag + drop onto the form) is "stThreadBlocking"
and has an event handler for get thread.

TServerSocket was the name. stThreadBlocking yes.

Quote:

//--------------------------------------------------------------------------
-
void __fastcall TForm1::ServerSocket1GetThread(TObject *Sender,
TServerClientWinSocket *ClientSocket, TServerClientThread
*&SocketThread)
{
SocketThread = new TMyServerThread(false, ClientSocket);
}

void __fastcall TForm1::SocketOpenClick(TObject *Sender)

If that is an eventhandler for a TButton then please let the name
as such when seeking help.

Quote:
void __fastcall TForm1::SocketCloseClick(TObject *Sender)
{
// close thread blocking socket
ServerSocket1->Active = false;
that is not enough I think.
}

Hans.

Back to top
Hans Galema
Guest





PostPosted: Wed Apr 06, 2005 6:02 pm    Post subject: Re: Help using sockets..... Reply with quote

Paul wrote:

Quote:
1) This comment in the tutorial seems to imply the approach isn't to drag
and drop a component....

Yes. Your'e supposed to. But the text is indeed misleading.

Be sure to make two separate aps. A server and a client with
resp. TServerSocket and TClientSocket.

A mix is confusing.

Hans.

Back to top
Paul
Guest





PostPosted: Wed Apr 06, 2005 6:15 pm    Post subject: Re: Help using sockets..... Reply with quote

The problem is that I always get the condition which gives the close socket,
and it 'never' reaches the following snippet. And it does this when the
client does the send text, so its not 60s timeout related.

// Back again to Client
pStream->Write( buffer, sizeof(buffer));

I've even closed down my ZoneAlarm firewall just to make sure its not
causing a problem. I'm running this test on W98SE, and have got all the
latest windows updates. Its driving me nuts! It should be so simple. Any
ideas?

Paul.


"Hans Galema" <notused (AT) notused (DOT) nl> wrote

Quote:
Paul wrote:
Right. I've tried the tutorial and I get the same problem.

Which problem ?

Every time the
server gets data it drops into the client socket close(), snippet below,
which is in the TMyServerThread.

if (pStream->Read(buffer, sizeof(buffer)) == 0)
// (if can't read in 60 seconds) than close the
connection
ClientSocket->Close();

Well it should only close after 60 seconds. Can you confirm that ?
And .. If you do not want to close then don't.

Can I confirm:
The client app component (drag + drop onto the form) is "ctNonBlocking"?

Pleas use the right names. You mean: The TClientSocket in this example
if of type ctNonBlocking ? yes.

The server app component (drag + drop onto the form) is
"stThreadBlocking"
and has an event handler for get thread.

TServerSocket was the name. stThreadBlocking yes.



//--------------------------------------------------------------------------
-
void __fastcall TForm1::ServerSocket1GetThread(TObject *Sender,
TServerClientWinSocket *ClientSocket, TServerClientThread
*&SocketThread)
{
SocketThread = new TMyServerThread(false, ClientSocket);
}

void __fastcall TForm1::SocketOpenClick(TObject *Sender)

If that is an eventhandler for a TButton then please let the name
as such when seeking help.

void __fastcall TForm1::SocketCloseClick(TObject *Sender)
{
// close thread blocking socket
ServerSocket1->Active = false;
that is not enough I think.
}

Hans.



Back to top
Hans Galema
Guest





PostPosted: Wed Apr 06, 2005 6:36 pm    Post subject: Re: Help using sockets..... Reply with quote

Paul wrote:
Quote:
The problem is that I always get the condition which gives the close socket,
and it 'never' reaches the following snippet.

The statement

ClientSocket->Close();

appears twice in the text. The second one you can outcomment
right away.

Quote:
if (pStream->WaitForData(CLIENTWAITTIME))

I see in my code that I replaced that by:

if (pStream->WaitForData(pStream->TimeOut))

Don't know why I did it. You can try.

Please start trimming your quotes.

Hans.

Back to top
Paul
Guest





PostPosted: Wed Apr 06, 2005 7:50 pm    Post subject: Re: Help using sockets..... Reply with quote

"Hans Galema" wrote

Quote:
if (pStream->WaitForData(pStream->TimeOut))

Tried this, no difference.

I also put Memo1 "debug" statements in the client application to check the
SendText() return value, and that seems to be ok (31 bytes).

I added another "debug" statement so that it recorded if the port was still
open on connecting (Button1Click), and it's never open. So I commented out
the first ClientSocket->Close() in the server application thread, and this
time the client application does say the port is open (Button1Click). But
even with this change, it still never gets to the following line in the
server application, so the pStream->Read() must always be returning zero:

// Back again to Client
pStream->Write( buffer, sizeof(buffer));

Paul.



Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Wed Apr 06, 2005 8:23 pm    Post subject: Re: Help using sockets..... Reply with quote


"Paul" <plmacca (AT) clara (DOT) co.uk> wrote


Quote:
Every time the server gets data it drops into the client socket
close(), snippet below, which is in the TMyServerThread.

If you are using a TWinSocketStream, then you are supposed to be calling its
WaitForData() method before calling Read(), if you are not already. If
WaitForData() returns true, then you are guaranteed to receive data
immediately in the Read(), unless the socket was actually disconnected, in
which case Read() will return 0 immediately instead.


Gambit



Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Wed Apr 06, 2005 8:27 pm    Post subject: Re: Help using sockets..... Reply with quote


"Paul" <plmacca (AT) clara (DOT) co.uk> wrote


Quote:
The problem is that I always get the condition which gives
the close socket, and it 'never' reaches the following snippet.

Please show a more complete snippet that shows everything you are doing.
You have shown nothing about the code that surrounds your reading and
writing, so there's no way to know if you are even handling the socket
properly in the first place.


Gambit



Back to top
Paul
Guest





PostPosted: Wed Apr 06, 2005 8:40 pm    Post subject: Re: Help using sockets..... Reply with quote

Its all as per the tutorial really. I may zip it up and try it on a XP
machine to see if its my W98SE installation, hopefully not.

Here's the server main form and thread:

__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//--------------------------------------------------------------------------
-
void __fastcall TForm1::ServerSocket1GetThread(TObject *Sender,
TServerClientWinSocket *ClientSocket, TServerClientThread
*&SocketThread)
{
SocketThread = new TMyServerThread(false, ClientSocket);
}
//--------------------------------------------------------------------------
-

void __fastcall TForm1::SocketOpenClick(TObject *Sender)
{
// open thread blocking socket
ServerSocket1->Active = true;
}
//--------------------------------------------------------------------------
-

void __fastcall TForm1::SocketCloseClick(TObject *Sender)
{
// close thread blocking socket
ServerSocket1->Active = false;
}
//--------------------------------------------------------------------------
-
void __fastcall TMyServerThread::ClientExecute(void)
{
// make sure connection is active
while (!Terminated && ClientSocket->Connected)
{
try
{
// Now, use TWinSocketStream to read or write information
// over a blocking socket connection
TWinSocketStream *pStream = new TWinSocketStream(ClientSocket,
CLIENTWAITTIME);

try
{
char buffer[BUFFERSIZE];
memset( buffer, 0, sizeof(buffer) );

// give the client 60 seconds to start writing
if (pStream->WaitForData(pStream->TimeOut))
{
if (pStream->Read(buffer, sizeof(buffer)) == 0)
{
// (if can't read in 60 seconds) than close the connection
// ClientSocket->Close();
}
else
{
// Client to Server test text
// Form1->Memo1->Lines->Add(AnsiString("(Client) ")
+AnsiString(buffer) );

// Back again to Client
pStream->Write( buffer, sizeof(buffer));
}

// ...
// Process requests here.
// ...

}
/*
else
{
ClientSocket->Close();
}
/**/
}
__finally
{
delete pStream;
}
}
catch (...)
{
HandleException();
}
}
}

And here's the client main form:

//--------------------------------------------------------------------------
-
__fastcall TForm2::TForm2(TComponent* Owner)
: TForm(Owner)
{
}
//--------------------------------------------------------------------------
-
void __fastcall TForm2::Button1Click(TObject *Sender)
{
AnsiString Server = ClientSocket1->Host;

if (ClientSocket1->Active)
{
Memo1->Lines->Add("Button Click : Port was open, now closed.");
ClientSocket1->Active = false;
}
if (InputQuery("Computer to connect to", "Address Name:", Server))
{
if (Server.Length() > 0)
{
ClientSocket1->Host = Server;
ClientSocket1->Active = true;
}
}
}
//--------------------------------------------------------------------------
-
void __fastcall TForm2::Button2Click(TObject *Sender)
{
ClientSocket1->Active = false;
}
//--------------------------------------------------------------------------
-
void __fastcall TForm2::ClientSocket1Read(TObject *Sender, TCustomWinSocket
*Socket)
{
Memo1->Lines->Add("Read Event Handler");

if (ClientSocket1->Active == true)
if (Socket->Connected == true)
Memo1->Lines->Add( AnsiString("(Server) ") +
Socket->ReceiveText() );
}
//--------------------------------------------------------------------------
-
void __fastcall TForm2::ClientSocket1Write(TObject *Sender, TCustomWinSocket
*Socket)
{
Memo1->Lines->Add("Write Event Handler");
if (ClientSocket1->Active == true)
{
Memo1->Lines->Add("..Port Active");
if (Socket->Connected == true)
{
AnsiString str = "....Send Text";
int i = Socket->SendText("This text is passed to and from");
str += i;
Memo1->Lines->Add(str);
}
}
}

Quote:
"Remy Lebeau (TeamB)" <no.spam (AT) no (DOT) spam.com> wrote


Please show a more complete snippet that shows everything you are doing.
You have shown nothing about the code that surrounds your reading and
writing, so there's no way to know if you are even handling the socket
properly in the first place.

Gambit




Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Wed Apr 06, 2005 10:42 pm    Post subject: Re: Help using sockets..... Reply with quote


"Paul" <plmacca (AT) clara (DOT) co.uk> wrote


Quote:
Its all as per the tutorial really.

Then I can tell you that the tutorial code has problems in it.

Quote:
void __fastcall TMyServerThread::ClientExecute(void)
{
// make sure connection is active
while (!Terminated && ClientSocket->Connected)
{
try
{
// Now, use TWinSocketStream to read or write information
// over a blocking socket connection
TWinSocketStream *pStream = new TWinSocketStream(ClientSocket,
CLIENTWAITTIME);

Rather than creating a new TWinSocketStream each time the loop reiterates, I
would suggest moving the TWinSocketStream creation to be outside of the
loop. That way, you create 1 new stream for each connection, not 1 new
stream for each individual read/write operation.

Quote:
// give the client 60 seconds to start writing
if (pStream->WaitForData(pStream->TimeOut))

There is a difference in meaning between the TimeOut property of the stream
and the Timeout parameter of WaitFor(). The TimeOut property only applies
to Read() and Write(). It controls how long they wait for data to actually
transmit before then returning. Then Timeout parameter of WaitFor(), on the
other hand, specified how long the stream waits for the socket be become
signaled as readable, meaning that data is available to be read, or the
socket has been disconnected.

Quote:
if (pStream->Read(buffer, sizeof(buffer)) == 0)
{
// (if can't read in 60 seconds) than close the
connection
// ClientSocket->Close();
}

You are not taking int account that Read() can return -1 if an error occurs.
You should also be storing the returnvalue into a variable, because Read()
specifies how much data was actually received, which you can then use later
in determining how much buffered data is actually available for processing.

Quote:
// Client to Server test text
// Form1->Memo1->Lines->Add(AnsiString("(Client) ")
+AnsiString(buffer) );

That code is not thread safe at all. You cannot safely access the GUI
directly from inside a worker thread. You need to use the thread's
Synchronize() method for that.

You are also not taking into account the condition where Read() received as
many bytes as the buffer can hold maximum. In which case, the buffer would
not be null-terminated. To work around that, you should be using
AnsiString's second constructor that takes a buffer length, so that you do
not accidentally convert the wrong memory.

int iRead = pStream->Read(buffer, sizeof(buffer);
//...
... = AnsiString(buffer, iRead);

Quote:
// Back again to Client
pStream->Write( buffer, sizeof(buffer));

You are not taking into account the actual return value of Read(), thus you
may be writing more data back to the client than it actually sent to begin
with.

int iRead = pStream->Read(buffer, sizeof(buffer));
//...
pStream->Write(buffer, iRead);

Quote:
HandleException();

I would suggest getting rid of that altogether. All it does is calls the
thread's Synchronize() method in order to show the exception in a popup
message. Not very useful to the rest of your code. If you are going to use
exception handling, then you should be prepared to process the exception
yourself.

Quote:
if (ClientSocket1->Active == true)
if (Socket->Connected == true)

Rather than doing that, call the Socket's ReceiveLength() method instead.
If it returns a value > 0 then there is data available to read. If Active
or Connected were false, the event would not be triggered in the first
place.

Quote:
void __fastcall TForm2::ClientSocket1Write(TObject *Sender,
TCustomWinSocket
*Socket)

You are misusing that event. It is only triggered when the connection is
first established, or when the socket becomes writable again after a
previous writing operation reported blocking when the socket is used in
non-blocking mode. Use the OnConnect event instead for the former, and
ignore the latter altogether as it will only complicate your code more than
it is currently set up to handle.


With that said, try this code instead:

--- Server ---

int __fastcall TMyServerThread::Read(TWinSocketStream *Stream, void
*Buffer, int BufSize)
{
try
{
int iRead = Stream->Read(Buffer, BufSize);
return (iRead < 0) ? 0 : iRead;
}
catch(const Exception &)
{
return 0;
}
}

bool __fastcall TMyServerThread::Write(TWinSocketStream *Stream, void
*Buffer, int BufSize)
{
LPBYTE pBuf = (LPBYTE) Buffer;

try
{
while( BufSize > 0 )
{
int iSent = Stream->Write(pBuf, pEnd-pBuf);
if( iSent <= 0 )
return false;

pBuf += iSent;
BufSize -= iSent;
}
return true;
}
catch(const Exception &)
{
return false;
}
}

void __fastcall TMyServerThread::ClientExecute(void)
{
char buffer[BUFFERSIZE];

TWinSocketStream *pStream = new TWinSocketStream(ClientSocket,
5000);
try
{
while( (!Terminated) && (ClientSocket->Connected) )
{
if( pStream->WaitForData(1000) )
{
int iRead = Read(pStream, buffer, sizeof(buffer));
if( iRead > 0 )
{
// declare FBuffer to be a member of the thread
class
FBuffer = AnsiString(buffer, iRead);
Synchronize(ReportBuffer);

// Process data here...

if( Write(pStream, buffer, iRead) )
continue;
}

ClientSocket->Close();
}
}
}
__finally
{
delete pStream;
}
}

void __fastcall TMyServerThread::ReportBuffer()
{
Form1->Memo1->Lines->Add("(Client) " + FBuffer);
}


--- Client ---

void __fastcall TForm2::ClientSocket1Read(TObject *Sender,
TCustomWinSocket *Socket)
{
Memo1->Lines->Add("Read Event Handler");

int iBytes = Socket->ReceiveLength();
if( iBytes > 0 )
Memo1->Lines->Add( "(Server) " + Socket->ReceiveText() );
}

void __fastcall TForm2::ClientSocket1Connect(TObject *Sender,
TCustomWinSocket *Socket)
{
Memo1->Lines->Add("Connect Event Handler");
Memo1->Lines->Add("..Port Active");
int i = Socket->SendText("This text is passed to and from");
Memo1->Lines->Add(i);
}


Now, with that said, I do not advise you to use SendText() and ReceiveText()
in the first place. They do not provide for adequate error handling, nor do
they help with handling split packets (where a packet requires multiple
read/writes in order to receive/send it all). A better implementation would
be as follows:

--- Server ---

bool __fastcall TMyServerThread::Read(TWinSocketStream *Stream, void
*Buffer, int BufSize)
{
LPBYTE pBuf = (LPBYTE) Buffer;

try
{
while( BufSize > 0 )
{
int iRead = Stream->Read(pBuf, BufSize);
if( iRead <= 0 )
return false;

pBuf += iRead;
BufSize -= iRead;
}
return true;
}
catch(const Exception &)
{
return false;
}
}

bool __fastcall TMyServerThread::Write(TWinSocketStream *Stream, void
*Buffer, int BufSize)
{
LPBYTE pBuf = (LPBYTE) Buffer;

try
{
while( BufSize > 0 )
{
int iSent = Stream->Write(pBuf, pEnd-pBuf);
if( iSent <= 0 )
return false;

pBuf += iSent;
BufSize -= iSent;
}
return true;
}
catch(const Exception &)
{
return false;
}
}

void __fastcall TMyServerThread::ClientExecute(void)
{
TWinSocketStream *pStream = new TWinSocketStream(ClientSocket,
5000);
try
{
while( (!Terminated) && (ClientSocket->Connected) )
{
if( pStream->WaitForData(1000) )
{
int iLength = 0;
if( Read(pStream, &iLength, sizeof(int)) )
{
FBuffer.SetLength(iLength);
if( Read(pStream, FBuffer.c_str(), iLength) )
{
Synchronize(ReportBuffer);

// Process data here...

if( Write(pStream, FBuffer.c_str(),
FBuffer.Length()) )
continue;
}

ClientSocket->Close();
}
}
}
__finally
{
delete pStream;
}
}

void __fastcall TMyServerThread::ReportBuffer()
{
Form1->Memo1->Lines->Add("(Client) " + FBuffer);
}


--- Client ---

// things get a bit trickier here since you are using a non-blocking
socket.
// you should be buffering the incoming data until you know that you
have
// received full packets, and only process full packets. You are NOT
// guaranteed to have a full packet available every time the OnRead
event
// is triggered.

class TMemoryBuffer : public TMemoryStream
{
public:
__fastcall TMemoryBuffer() : TMemoryStream() {}

int Available() { return (Size - Position); }

void* Expand(int Count)
{
int Old = Size;
Size = (Old + Count);

return ( ((LPBYTE) Memory) + Old );
}

void Remove(int Count)
{
int iAvailable = Available();
if( Count > iAvailable )
Count = iAvailable;

int NewSize = (Size - Count);
if( NewSize != Size )
{
if( NewSize < Size )
{
void *ptr = ( ((LPBYTE) Memory) + Position );
::MoveMemory(Memory, ptr, NewSize);
Size = NewSize;
}
else
Clear();

Position = 0;
}
}
};


TMemoryBuffer *InBuffer = NULL;
TMemoryBuffre *OutBuffer = NULL;

__fastcall TForm2::TForm2(TComponent *Owner)
: TForm(Owner)
{
InBuffer = new TMemoryBuffer;
OutBuffer = new TMemoryBuffer;
}

__fastcall TForm2::~TForm2()
{
delete InBuffer;
delete OutBuffer;
}

void __fastcall TForm2::ClientSocket1Connect(TObject *Sender,
TCustomWinSocket *Socket)
{
Memo1->Lines->Add("Connect Event Handler");
Memo1->Lines->Add("..Port Active");
InBuffer->Clear();
OutBuffer->Clear();
Write(ClientSocket1->Socket, "This text is passed to and from", 31);
}

void __fastcall TForm2::ClientSocket1Disconnect(TObject *Sender,
TCustomWinSocket *Socket)
{
Memo1->Lines->Add("Disconnect Event Handler");
Memo1->Lines->Add("..Port not Active");
InBuffer->Clear();
OutBuffer->Clear();
}

void __fastcall TForm2::ClientSocket1Error(TObject* Sender,
TCustomWinSocket* Socket, TErrorEvent ErrorEvent, int &ErrorCode)
{
Memo1->Lines->Add("Client Error: " + AnsiString(ErrorCode) );
Socket->Close();
ErrorCode = 0;
}

void __fastcall TForm2::ClientSocket1Read(TObject *Sender,
TCustomWinSocket *Socket)
{
Memo1->Lines->Add("Read Event Handler");

int Bytes = Socket->ReceiveLength();
if( Bytes > 0 )
{
char *ptr = (char*) InBuffer->Expand(Bytes);
Socket->ReceiveBuf(ptr, Bytes);

while( InBuffer->Available() >= sizeof(int) )
{
int Length = 0;
InBuffer->Read(&Length, sizeof(int));

if( InBuffer->Available() < Length )
{
InBuffer->Seek(-sizeof(int), soFromCurrent);
break;
}

ptr = ( ((char*) InBuffer->Memory) + InBuffer->Position );
InBuffer->Seek(Length, soFromCurrent);

Memo1->Lines->Add("(Server) " + AnsiString(ptr, Length));
}

InBuffer->Remove(InBuffer->Position);
}

void __fastcall TForm2::ClientSocket1Write(TObject *Sender,
TCustomWinSocket *Socket)
{
LPBYTE pBuf = (LPBYTE) OutBuffer->Memory
int BufSize = OutBuffer->Size;

if( BufSize > 0 )
{
do
{
int iSent = Socket->SendBuf(pBuf, BufSize);
if( iSent < 1 )
{
if( iSent == 0 )
return; // disconnected

// try the data again later
break;
}

pBuf += iSent;
BufSize -= iSent;
}
while( BufSize > 0 );

OutBuffer->Remove(OutBuffer->Size - BufSize);
}
}

void __fastcall TForm1::Write(TCustomWinSocket *Socket, void *Buffer,
int BufSize)
{
if( OutBuffer->Size > 0 )
{
// socket still has pending data from previous
// write so try this data again later
OutBuffer->Write(Buffer, BufSize);
}
else
{
LPBYTE pBuf = (LPBYTE) Buffer;
while( BufSize > 0 )
{
int iSent = Socket->SendBuf(pBuf, BufSize);
if( iSent < 1 )
{
if( iSent == 0 )
return; // disconnected

// try the data again later
if( Socket->Connected )
OutBuffer->Write(pBuf, BufSize);
break;
}

pBuf += iSent;
BufSize -= iSent;
}
}
}


Gambit



Back to top
Paul
Guest





PostPosted: Thu Apr 07, 2005 6:27 am    Post subject: Re: Help using sockets..... Reply with quote

All in all then not really a good tutorial. If my s/w manager came back
with this many comments after a code review I'd feel gutted.

This is going to take a little while to digest and try out. I'll let you
know how I get on. Many thanks for your input.


"Remy Lebeau (TeamB)" <no.spam (AT) no (DOT) spam.com> wrote

Quote:

"Paul" <plmacca (AT) clara (DOT) co.uk> wrote in message
news:425448ec$1 (AT) newsgroups (DOT) borland.com...

Its all as per the tutorial really.

Then I can tell you that the tutorial code has problems in it.




Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> C++ Builder (Internet Socket) All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.