🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: borland.public.cppbuilder.internet.socket
7 messages
7 total messages Started by enzo Thu, 01 Dec 2005 10:29
Modify the timeout for open() method
#3068
Author: enzo
Date: Thu, 01 Dec 2005 10:29
7 lines
1123 bytes
I'm using a standard TClientSocket to connect to some servers.
When the server is down the Open() call wait several seconds before abort
for timeout.
I need to short this timeout during the open to a value of 1 second.
Is that possible , and if it is how can I do it ?

regards, enzo
Re: Modify the timeout for open() method
#3070
Author: Remy Lebeau (TeamB)
Date: Thu, 01 Dec 2005 18:32
28 lines
2085 bytes
"enzo" <enzo.arlati@aesys.it> wrote in message
news:438ed040@newsgroups.borland.com...

> I'm using a standard TClientSocket to connect to some servers.
> When the server is down the Open() call wait several seconds
> before abort for timeout.

Are you using the TClientSocket in blocking or non-blocking mode?

In non-blocking mode, Open() should be returning almost immediately
regardless of whether the connection is successful or not.  You will be
notified later on if the connection is established or not.  You can start a
timer as soon as Open() returns, and then disconnect the socket if the timer
elapses.  If the connection succeeds, stop the timer.

In blocking mode, you will have to use a separate worker thread to
disconnect the socket if it is not connected after your timeout elapses.

Also, try to use the Address property instead of the Host property if you
can.  The Host property performs a DNS lookup when Open() is called, which
takes extra time.  The Address property does not perform any DNS lookup.
This is because DNS is used to resolve a hostname into an IP address, and
the Address property only works with IP addresses so no DNS lookup is
needed.


Gambit
Re: Modify the timeout for open() method
#3073
Author: enzo
Date: Fri, 02 Dec 2005 07:57
26 lines
2057 bytes
"Remy Lebeau (TeamB)" <no.spam@no.spam.com> ha scritto nel messaggio
news:438f4204$1@newsgroups.borland.com...
>
> "enzo" <enzo.arlati@aesys.it> wrote in message
> news:438ed040@newsgroups.borland.com...
> Are you using the TClientSocket in blocking or non-blocking mode?
>
> In blocking mode, you will have to use a separate worker thread to
> disconnect the socket if it is not connected after your timeout elapses.

I create and open the socket in blocking mode from inside a thread.
As the example belowe :
           clientSck = new TClientSocket( NULL );
           clientSck->ClientType = ctBlocking;
           clientSck->Address = ipTarge;
           clientSck->Port = portTarget;
           clientSck->Open();
           if( clientSck->Active == false ) return;

I need to make a fast check before call the open or mybe shorten the timeout
if I call open on a pc not ready to listen.
what do you mean for a separate thread to disconnect the socket, can you
provide me an example ?

thanks, Enzo
Re: Modify the timeout for open() method
#3074
Author: enzo
Date: Fri, 02 Dec 2005 09:31
60 lines
3126 bytes
"enzo" <enzo.arlati@aesys.it> ha scritto nel messaggio
news:438ffe59@newsgroups.borland.com...
>
> "Remy Lebeau (TeamB)" <no.spam@no.spam.com> ha scritto nel messaggio
> news:438f4204$1@newsgroups.borland.com...
> >
> > "enzo" <enzo.arlati@aesys.it> wrote in message
> > news:438ed040@newsgroups.borland.com...
> > Are you using the TClientSocket in blocking or non-blocking mode?
> >
> > In blocking mode, you will have to use a separate worker thread to
> > disconnect the socket if it is not connected after your timeout elapses.
>
> I create and open the socket in blocking mode from inside a thread.
> As the example belowe :
>            clientSck = new TClientSocket( NULL );
>            clientSck->ClientType = ctBlocking;
>            clientSck->Address = ipTarge;
>            clientSck->Port = portTarget;
>            clientSck->Open();
>            if( clientSck->Active == false ) return;
>
> I need to make a fast check before call the open or mybe shorten the
timeout
> if I call open on a pc not ready to listen.
> what do you mean for a separate thread to disconnect the socket, can you
> provide me an example ?
>
> thanks, Enzo


I solved using a solution like this.
Application->ProcessMessages() used inside a thread should not be a good
idea, but for now is working.
I hope someone of your guys have a better idea.

           clientSck = new TClientSocket( NULL );
           clientSck->ClientType = ctNonBlocking;
           clientSck->Address = ipTargetFep;
           clientSck->Port = portTargetFep;
           clientSck->Open();

           for( int idx = 0; idx < 10; idx++ )
           {
             Application->ProcessMessages();
             Sleep( 10 );
             if( clientSck->Socket->Connected == true ) break;
           }

           if( clientSck->Socket->Connected == false )
           {
              mylog(  Format( "[ClientXML] Connessione al server %s FALLITA
", ARRAYOFCONST(( ipTargetFep ))));
              return;
           }
           clientSck->Close();

           clientSck->ClientType = ctBlocking;
           clientSck->Open();
Re: Modify the timeout for open() method
#2976
Author: Remy Lebeau (TeamB)
Date: Fri, 02 Dec 2005 19:12
85 lines
3209 bytes
"enzo" <enzo.arlati@aesys.it> wrote in message
news:438ffe59@newsgroups.borland.com...

> I create and open the socket in blocking mode from inside a thread.

You need another thread in order to abort a blocking Open().

> I need to make a fast check before call the open

There is no way to do that.  The only way to know if a socket is listening
on another machine is to connect to it.

> or mybe shorten the timeout if I call open on a pc not ready to listen.

Like I told you before, there is no connect timeout available.  You have to
implement your own.

> what do you mean for a separate thread to disconnect the socket

I mean exactly what I say.  The only way to abort a blocking Open() is to
disconnect the socket from the context of a different thread than the one
that is calling Open().  For example (untested):

    class TConnectThread : public TThread
    {
    private:
        TClientSocket *FSocket;
    protected:
        virtual void __fastcall Execute();
    public:
        __fastcall TConnectThread(TClientSocket *ASocket);
    };

    __fastcall TConnectThread::TConnectThread(TClientSocket *ASocket)
        : TThread(true)
    {
        FSocket = ASocket;
        Resume();
    }

    void __fastcall TConnectThread::Execute()
    {
        try
        {
            FSocket->Open();
        }
        catch(const Exception &) {}
    }


    __fastcall TSocketThread::TSocketThread()
        : TThread(true)
    {
        clientSck = new TClientSocket( NULL );
        clientSck->ClientType = ctBlocking;
        Resume();
    }

    __fastcall TSocketThread::~TSocketThread()
    {
        delete clientSck;
    }

    void __fastcall TSocketThread::Execute()
    {
        //...
        clientSck->Address = ipTarge;
        clientSck->Port = portTarget;

        TConnectThread *CT = new TConnectThread(clientSck);
        if( WaitForSingleObject((HANDLE)CT->Handle, 1000) != WAIT_OBJECT_0 )
        {
            clientSck->Close();
            CT->WaitFor();
        }
        delete CT;

        if( !clientSck->Active ) return;

        // ...
    }


Gambit
Re: Modify the timeout for open() method
#2977
Author: Remy Lebeau (TeamB)
Date: Fri, 02 Dec 2005 19:20
53 lines
2964 bytes
"enzo" <enzo.arlati@aesys.it> wrote in message
news:43901442$1@newsgroups.borland.com...

> Application->ProcessMessages() used inside a thread should
> not be a good idea, but for now is working.

You are right that it is not a good idea.  ProcessMessages() is not designed
to be called from outside of the main thread.  It is not a thread-safe
method.  DO NOT call ProcessMessages() from the context of a worker thread.
If you must use a non-blocking socket in a thread, then you should write
your own message queue manually by calling PeekMessage(), TranslateMessage()
and DispatchMessage() instead of ProcessMessages(), ie:

    clientSck = new TClientSocket( NULL );
    clientSck->ClientType = ctNonBlocking;
    clientSck->Address = ipTargetFep;
    clientSck->Port = portTargetFep;
    clientSck->Open();

    MSG msg;
    for(int idx = 0; (idx < 100) && (!clientSck->Active); ++idx)
    {
        if( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) )
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        Sleep(10);
    }

    if( !clientSck->Active )
    {
        //...
    }


>           clientSck->Close();
>           clientSck->ClientType = ctBlocking;
>           clientSck->Open();

Why are you closing the socket immediately after opening it?  You should not
be doing that.  There is no guarantee that the second Open() will succeed,
so you'll be right back to square one again.

If you really want to use a blocking socket in a thread with a connect
timeout, then I suggest not using TClientSocket in the first place.  Use
Indy (http://www.indyproject.org) instead.  It uses blocking sockets for
everything and is designed to be used with threading.  Its TIdTCPClient
component has a connect timeout available.


Gambit
Re: Modify the timeout for open() method
#2984
Author: enzo
Date: Mon, 05 Dec 2005 10:03
94 lines
3535 bytes
thanks, it works well and seems a very good solution.


"Remy Lebeau (TeamB)" <no.spam@no.spam.com> ha scritto nel messaggio
news:43909cb3$1@newsgroups.borland.com...
>
> "enzo" <enzo.arlati@aesys.it> wrote in message
> news:438ffe59@newsgroups.borland.com...
>
> > I create and open the socket in blocking mode from inside a thread.
>
> You need another thread in order to abort a blocking Open().
>
> > I need to make a fast check before call the open
>
> There is no way to do that.  The only way to know if a socket is listening
> on another machine is to connect to it.
>
> > or mybe shorten the timeout if I call open on a pc not ready to listen.
>
> Like I told you before, there is no connect timeout available.  You have
to
> implement your own.
>
> > what do you mean for a separate thread to disconnect the socket
>
> I mean exactly what I say.  The only way to abort a blocking Open() is to
> disconnect the socket from the context of a different thread than the one
> that is calling Open().  For example (untested):
>
>     class TConnectThread : public TThread
>     {
>     private:
>         TClientSocket *FSocket;
>     protected:
>         virtual void __fastcall Execute();
>     public:
>         __fastcall TConnectThread(TClientSocket *ASocket);
>     };
>
>     __fastcall TConnectThread::TConnectThread(TClientSocket *ASocket)
>         : TThread(true)
>     {
>         FSocket = ASocket;
>         Resume();
>     }
>
>     void __fastcall TConnectThread::Execute()
>     {
>         try
>         {
>             FSocket->Open();
>         }
>         catch(const Exception &) {}
>     }
>
>
>     __fastcall TSocketThread::TSocketThread()
>         : TThread(true)
>     {
>         clientSck = new TClientSocket( NULL );
>         clientSck->ClientType = ctBlocking;
>         Resume();
>     }
>
>     __fastcall TSocketThread::~TSocketThread()
>     {
>         delete clientSck;
>     }
>
>     void __fastcall TSocketThread::Execute()
>     {
>         //...
>         clientSck->Address = ipTarge;
>         clientSck->Port = portTarget;
>
>         TConnectThread *CT = new TConnectThread(clientSck);
>         if( WaitForSingleObject((HANDLE)CT->Handle, 1000) !=
WAIT_OBJECT_0 )
>         {
>             clientSck->Close();
>             CT->WaitFor();
>         }
>         delete CT;
>
>         if( !clientSck->Active ) return;
>
>         // ...
>     }
>
>
> 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