🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: borland.public.cppbuilder.internet.socket
4 messages
4 total messages Started by Vladimir Stefanovic Wed, 18 Aug 2004 07:19
What is actually happening with this simple (TCS/TSS) example?
#5327
Author: Vladimir Stefanovic
Date: Wed, 18 Aug 2004 07:19
79 lines
3026 bytes
Hi,

I have some misunderstanding of behavior of simple sending
strings from TClientSocket to TServerSocket in some cases.

The server's code is the same in all cases. Server is supposed
to read text and display it in Memo1. ServerSocket1 is set to
'Active = true' and 'ServerType = stNonBlocking' at design-time.
Port is also set to 1101 at both sides at design-time. All examples
are tested on a single PC.

   // Server reading/displaying code ...
   void __fastcall TForm1::ServerSocket1ClientRead(TObject *Sender,
         TCustomWinSocket *Socket)
   {
      Memo1->Lines->Add( Socket->ReceiveText() );
   }


   // Client sending code...

CASE 1: ( Works )
   Design-Time:
      Active=true;
      ClientType=ctNonBlocking;
      Address=128.128.129.162;
   
   void __fastcall TForm1::SendButtonClick(TObject *Sender)
   {
      ClientSocket1->Socket->SendText( "Test!" );
   }


CASE 2: ( Does NOT work when ctNonBlocking )

   Design-Time:
      Active=false;
      ClientType=ctNonBlocking; // <-- works when ctBlocking
      Address=[Empty];

   void __fastcall TForm1::SendButtonClick(TObject *Sender)
   {
      if ( ClientSocket1->Active == true )
         ClientSocket1->Close();
      ClientSocket1->Address="128.128.129.162";
      ClientSocket1->Open();
      ClientSocket1->Socket->SendText( "Test!" );
   }


CASE 3: (Works on second and all other SendButton clicks, but
fails on first click ?! Also tried with...
   if ( Socket->ReceiveLength() < 1 )
      return;
... but no changes. When tested on LAN (not on a single PC) does
not work at all.

   Design-Time:
      Active=false;
      ClientType=ctNonBlocking;
      Address=[Empty];

   void __fastcall TForm1::SendButtonClick(TObject *Sender)
   {
      if ( ClientSocket1->Active == true )
         ClientSocket1->Close();
      ClientSocket1->Address="128.128.129.162";
      ClientSocket1->Open();
      Application->ProcessMessages(); // <-- This line was added
      ClientSocket1->Socket->SendText( "Test!" );
   }


Why all this works in Blocking mode and not in NonBlocking?


Best regards,
Vladimir Stefanovic
Re: What is actually happening with this simple (TCS/TSS) example?
#5329
Author: Remy Lebeau (TeamB)
Date: Wed, 18 Aug 2004 17:55
58 lines
2953 bytes
"Vladimir Stefanovic" <antivari@ptt.yu> wrote in message
news:41230302$1@newsgroups.borland.com...

>    void __fastcall TForm1::SendButtonClick(TObject *Sender)
>    {
>       if ( ClientSocket1->Active == true )
>          ClientSocket1->Close();
>       ClientSocket1->Address="128.128.129.162";
>       ClientSocket1->Open();
>       ClientSocket1->Socket->SendText( "Test!" );
>    }

In non-blocking mode, you can't send data until the TClientSocket's
OnConnect event has been triggered, which won't happen in that code example
because non-blocking sockets require a message queue for triggering socket
events.  Calling Open() posts a message to the message queue to trigger the
OnConnect event at a later time, which you have to wait for before then
sending your data.  For example:

    void __fastcall TForm1::SendButtonClick(TObject *Sender)
    {
        if ( ClientSocket1->Active )
            ClientSocket1->Close();
        ClientSocket1->Address="128.128.129.162";
        ClientSocket1->Open();
    }

    void __fastcall TForm1::ClientSocket1Connect(TObject *Sender,
TCustomWinSocket *Socket)
    {
        Socket->SendText( "Test!" );
    }

> CASE 3: (Works on second and all other
> SendButton clicks, but fails on first click ?!

You probably just aren't calling ProcessMessages() often enough.  You would
have to keep calling it until the socket actually finishes connecting, ie:

    void __fastcall TForm1::SendButtonClick(TObject *Sender)
    {
        if ( ClientSocket1->Active )
            ClientSocket1->Close();
        ClientSocket1->Address="128.128.129.162";
        ClientSocket1->Open();
        while( !ClientSocket1->Socket->Connected )    // <-- added this
            Application->ProcessMessages();
        ClientSocket1->Socket->SendText( "Test!" );
    }

> Why all this works in Blocking mode and not in NonBlocking?

Because you are not taking message handling into account properly.  Blocking
mode does not use messages at all.


Gambit
Re: What is actually happening with this simple (TCS/TSS) example?
#5330
Author: Vladimir Stefanovic
Date: Wed, 18 Aug 2004 19:14
13 lines
1285 bytes
Thanks for the detailed explanations.

> >       if ( ClientSocket1->Active )
> >          ClientSocket1->Close();

Is there any specific benefit of checking if connection is
active (except of good programming style), because we
have to close it anyway to change params?



Best regards,
Vladimir Stefanovic
Re: What is actually happening with this simple (TCS/TSS) example?
#5331
Author: Remy Lebeau (TeamB)
Date: Wed, 18 Aug 2004 19:59
13 lines
1353 bytes
"Vladimir Stefanovic" <spam@not.needed> wrote in message
news:4123aa91@newsgroups.borland.com...

> Is there any specific benefit of checking if connection is
> active (except of good programming style), because we
> have to close it anyway to change params?

Not really.  Calling Close() on a socket that is already disconnected simply
won't do anything.


Gambit
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads