-
March 9th, 2011, 04:41 AM
#1
CAsyncSocket with Timeout
Hey there,
I got a project where I should work on, which implemented a Client/Server Application, where the Client is sending a string, and the server is storing it into a file. Searching about more details, I saw that the architecture is mostly taken from this source: http://www.codeproject.com/KB/IP/MFC...82#xx3799782xx
I have three cpp files, derivated from CWinApp, CDialog and CAsyncSocket, and now I have to add a timeout on the whole thing, which means: when the Client is not sending any data for about two minutes, the connection should shut down and then open again and waiting for the Client to establish the Connection again.
I am a very C++ newbie, and I am reading articles since two or three days, but I don't get any idea how to implement it for my application. I also found something for CSocket here: http://support.microsoft.com/kb/138692 but CAsyncSocket can't use this, because it don't know the functions CancelBlockingCall() and CSocket::OnMessagePending().
Maybe anybody has a hint for me how I can go on?
Best regards,
L.
-
March 9th, 2011, 08:30 AM
#2
Re: CAsyncSocket with Timeout
Inbetween I thought that I had found something... with SetSockOpt. But it's not working. I think it's to detect if the connection is closed, and then I get a message anyway. So I never see this "Timeout!!!" CString. But how can I detect when the Client has still an open connection, but don't use it?
void CEchoServerDlg::OnAccept()
{
CString strIP;
UINT port;
BOOL fOptval = TRUE;
if(m_sListener.Accept(m_sConnected))
{
if(m_sConnected.SetSockOpt(SO_KEEPALIVE, &fOptval, sizeof(BOOL)) == FALSE)
AfxMessageBox(CString("Timeout!!!"));
else
{
m_sConnected.GetSockName(strIP,port);
m_status="Client Connected,IP :"+ strIP;
m_sConnected.Send("Connected To Server",strlen("Connected To Server"));
UpdateData(FALSE);
}
}
-
March 9th, 2011, 03:14 PM
#3
Re: CAsyncSocket with Timeout
I can think of two methods off-hand:
Initialize a Windows timer in the OnAccept function, and reset it (to two minutes) in OnReceive for every instance where you actually receive data. When the timer fires, then in the handler for the timer, call the socket's Close function.
Or, if you have multiple clients that connect to your server, then add a member to your socket class called m_LastReceivedTime. Initialize it to current time in OnAccept and set it to current time in every OnReceive. Then have a Windows timer fire at a fairly reasonable interval, such as every 1 or 5 seconds. In the timer handler, go through the list of all active sockets and check the m_LastReceivedTime variable for staleness. If the variable indicates inactivity for more than two minutes, call Close on the affected socket.
Mike
PS: The CTimeoutSocket you found on MSDN is not needed here, and probably wouldn't work anyway. CTimeoutSocket is based on CSocket which is a blocking socket. Since the socket is blocking, calls to various socket functions will block the progress of the entire application, and some technique is needed to break out of the blocking call (hence the CTimeoutSocket class). In contrast, your socket class derives from CAsyncSocket which is a non-blocking socket. Since calls to these socket functions do not block progress of the entire application, other and simpler techniques are available to you, such as the two ideas mentioned above.
-
March 14th, 2011, 08:58 AM
#4
Re: CAsyncSocket with Timeout
Thank you for your answer, MikeAThon, as I only have one Client at this time, I will try the first solution with the timer and then post again if it worked or not.
-
March 14th, 2011, 09:52 AM
#5
Re: CAsyncSocket with Timeout
Wow, that was fast and easy!
Found two (german) sources where it was explained: http://forum.fachinformatiker.de/c-c...unction-c.html and http://www.c-plusplus.de/forum/70264, now it's working.
For all who have the same problem and maybe even use the same sourcecode, here's the solution:
Add
#define MYTIMER 10000
in EchoServerDlg.cpp
In the function void CEchoServerDlg::OnAccept() I set the timer to two minutes:
SetTimer(MYTIMER,120*1000,NULL); // 120*1000 ms = 120 s
and then added this function:
void CEchoServerDlg::OnTimer(UINT_PTR nIDEvent)
{
// TODO: Fügen Sie hier Ihren Meldungsbehandlungscode ein, und/oder benutzen Sie den Standard.
OnClose();
m_status="Timeout!!";
CDialog::OnTimer(nIDEvent);
}
Now I get a timeout after two minutes
Oops, I just see that I forgot to reset it when receiving the data, but this should also be easy.
Thanks again, MikeAThon!
-
March 14th, 2011, 11:08 AM
#6
Re: CAsyncSocket with Timeout
Reset is not complicated, just another call of:
SetTimer(MYTIMER,30*1000,NULL); // 120*1000 ms = 120 s
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|