Thread View: borland.public.cppbuilder.internet.socket
2 messages
2 total messages
Started by JohnG
Wed, 27 Feb 2008 13:52
Keep Alive & reconnecting
Author: JohnG
Date: Wed, 27 Feb 2008 13:52
Date: Wed, 27 Feb 2008 13:52
64 lines
2472 bytes
2472 bytes
Hi,
I am using C++ Builder 2006 with indy 9 (9.0.50?) components.
I believe the "Keep Alive" code I have implemented in negatively
affecting the TIdTCPClients ability to reconnect to the
TidTCPServer. When a client reconnects prior to the server
realizing that the connection was severed, the client
disconnects immediately after reconnecting.
I believe (guess) that the Keep Alive code is in the process of
failing as the client is reconnecting. If I remove the Keep
Alive code, reconnections always succeeds. If I wait until the
server realizes that the connections have severed, reconnections
always succeed.
I have the following code in a TimerEvent ( every 10 seconds)
as my implementation of "Keep Alive" code between clients
(TidTCPClient) and server
//code to ping\keep alive to all connected clients
TList *list = IdTCPServer->Threads->LockList();
try
{
for( int i = 0 ; i < list->Count ; i++)
{
TIdPeerThread *thread = static_cast<TIdPeerThread*>(list->Items[i]);
if (thread->Connection->Socket->Connected())
{
strResponse = SendMessageToClient(thread,strPING,8000 /* timeout value*/);
}
else
{
//return faillure
}
}
}
catch(...)
{
IdTCPServer->Threads->UnlockList();
}
IdTCPServer->Threads->UnlockList();
//----------------------------------------------
The rest of my implementation is similar to this
http://tinyurl.com/2bq4vt
Any ideas or suggestions on how to prevent the keep alive code
from affecting cient reconnections will be greatly appreciated.
Regards,
JohnG
Re: Keep Alive & reconnecting
Author: Remy Lebeau (TeamB)
Date: Wed, 27 Feb 2008 18:27
Date: Wed, 27 Feb 2008 18:27
93 lines
3940 bytes
3940 bytes
"JohnG" <whatis@email.com> wrote in message
news:47c57942$1@newsgroups.borland.com...
> I believe the "Keep Alive" code I have implemented in
> negatively affecting the TIdTCPClients ability to reconnect
> to the TidTCPServer. When a client reconnects prior to
> the server realizing that the connection was severed, the
> client disconnects immediately after reconnecting.
You should not be calling Connected() in your loop at all. Just send the
ping and catch any error that may occur.
> I believe (guess) that the Keep Alive code is in the process
> of failing as the client is reconnecting.
That would not have any effect on it. Your loop knows which threads to send
to. If a client reconnects, it is going to have a completely new thread.
Sending a ping to a previous thread will not effect the new thread at all.
> I have the following code in a TimerEvent ( every 10 seconds)
> as my implementation of "Keep Alive" code between clients
> (TidTCPClient) and server
I would not suggest using such a timed loop at all. Let the OnExecute event
handler perform the actual keepalive on a per-client basis for you. You
shouldn't be sending a ping unless a connection has actually been idle for
awhile. For example (untested):
class TMyPeerThread : public TIdPeerThread
{
public:
TDateTime LastRecv;
__fastcall TMyPeerThread(bool ACreateSuspended = true);
};
__fastcall TMyPeerThread::TMyPeerThread(bool ACreateSuspended)
: TIdPeerThread(ACreateSuspended)
{
}
__fastcall TForm1::TForm1(TComponent *Owner)
: TForm(Owner)
{
IdTCPServer1->ThreadClass = __classid(TMyPeerThread);
}
void __fastcall TForm1::IdTCPServer1Connect(TIdPeerThread *AThread)
{
AThread->Connection->ReadTimeout = 10000;
static_cast<TMyPeerThread*>(AThread)->LastRecv = Now();
}
void __fastcall TForm1::IdTCPServer1Execute(TIdPeerThread *AThread)
{
TMyPeerThread *LThread = static_cast<TMyPeerThread*>(AThread);
TDateTime dtNow = Now();
if( LThread->Connection->InputBuffer->Size == 0 )
{
if( LThread->Connection->ReadFromStack(true, IdTimeoutDefault,
false) < 0 )
{
if( SecondsBetween(dtNow, LThread->LastRecv) < 30 )
{
// write PING command as needed. do not wait for a
reply...
}
else
AThread->Connection->Disconnect();
return;
}
}
LThread->LastRecv = dtNow;
// handle inbound data as needed...
}
> catch(...)
> {
> IdTCPServer->Threads->UnlockList();
> }
>
> IdTCPServer->Threads->UnlockList();
If an exception occurs in your loop, you are calling UnlockList() twice.
Don't do that.
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