Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 803
  • Last Modified:

Network connection with CAsyncSocket

Hi,

   I've created a client application which uses CAsyncSocket to retrieve data from a server. The problem occurs when my router is down or when I pull out my network cable. When I call CAsyncSocket::Connect, the application hangs. When I have network connection, all is fine but when I have a problem with it, the application hangs. I do recieve server down messages and other errors, but when my local network is down, I don't recieve any notification.
0
gilad_no
Asked:
gilad_no
  • 15
  • 11
  • 3
1 Solution
 
jhanceCommented:
It's doing exactly what it's supposed to do.  CAsyncSocket::Connect waits for a connection and will send a message to your calling thread when it gets one.

If you want to timeout, then set a timer when you call Connect and if the connection doesn't happen in that amount of time, call ShutDown and Close on the socket and report that problem to the user or try again.
0
 
gilad_noAuthor Commented:
So, I create a thread (Thread1) which will create the socket.
in Thread2 I wait for 30 seconds (for example) and if the socket is still trying to connect I call to ShutDown and close it ? Is it safe to do shut it down from another thread ?
0
 
gilad_noAuthor Commented:
Can I use a timer for this instead of threads ?

...
nTimer=SetTimer(0,30,NULL);
if (m_Socket.Connect(szServer,nPort))
{
    KillTimer(nTimer);
    // Continue

}
else
  {
    KillTimer(nTimer);
    Close();
  }
...
void OnTimer(UINT nIDEvent)
{
   m_Socket.ShutDown();
}


Is this OK ? Can I use that code ? If I call ShutDown does Connect returns FALSE ?
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
jhanceCommented:
I didn't say anything about a thread.  One should not be needed.  Just set a timer in your app and when it expires kill the socket if it's not done what you wanted it to do.

BTW, the Connect call should eventually expire on its own but it could take a while.
0
 
gilad_noAuthor Commented:
If I shut it down, would it return FALSE immediately ?
0
 
gilad_noAuthor Commented:
If I shut it down, would it return FALSE immediately ?
0
 
gilad_noAuthor Commented:
jhance,

   I've tried the timer but as soon as I call to CAsyncSocket::Connect, the application stop responding if I don't have internet access
0
 
jhanceCommented:
The call to CASyncSocket::Connect should return to you immediately regardless of whether or not there is any connection made.

Show your code....
0
 
ShaunWildeCommented:
have a look at http://support.microsoft.com/support/kb/articles/Q138/6/92.asp it shows how to configure a timeout on a CSocket since you seem to be using stream sockets this is the class you should be using ( and you can use it without all the CSocketFile baggage if you wish )

also have a look at

http://www.codeguru.com/internet/timeoutsocket.shtml
0
 
gilad_noAuthor Commented:
I don't want to use CSocket. I need CAsyncSocket because I don't want the blocking feature. I've tried to use the timer like that:

CAsyncSocket  *pSocket;

void MyTimer(HWND hWnd,UINT nMsg,UINT_PTR nTimerID,DWORD dwTimer)
{
  pSocket->ShutDown();
}

...

pSocket=this;
UINT nTimer=::SetTimer(NULL,10000,(TIMERPROC)&MyTimer);
BOOLEAN bResult=Connect(szServer,nPort);
::KillTimer(nTimer);
if (bResult)
{

}
else
{

}

When I call "Connect", the application hangs. It works in case I do have network connection, but if I pull the cable out, it hangs.
0
 
ShaunWildeCommented:
are you using SOCK_STREAM or SOCK_DGRAM (stream or datagrams) ? stream sockets are blocking sockets

> When I call "Connect", the application hangs. It works in case I do have network connection, but if
I pull the cable out, it hangs.

yes because the CSocket class is designed to handle SOCK_STREAM better and has a connecthelper method that can be overridden
0
 
ShaunWildeCommented:
if yow want to move the socket off blocking you will have to use

DWORD ul=1;
sock.IOCtl(FIONBIO,&ul);

but any call to asyncSelect or equivalent will pop it back into blocking mode
0
 
gilad_noAuthor Commented:
My application need to connet to my server to retrieve some information. I don't want to use blocking sockets because if I need to retrieve some big data and the user connection is low, it could take a lot of time until the application get control back. I want it to work while it wait for data from the server. I took the code from Gnutella (the self update method) and modified it a little. Is there any other way to do it ? Beside that problem when there is no network connection, it works great
0
 
ShaunWildeCommented:
you could try testing to see if the connection is there by using a udp ping and then once you have verified that something exists at the ip address try connecting using tcp
0
 
gilad_noAuthor Commented:
I've tried it some time ago. There are times that I get no ping response from the server even when it's ok. I can connect it but I can't ping it.
0
 
ShaunWildeCommented:
> There are times that I get no ping response from the server even when it's ok. I can connect it but I can't ping it.

most people using this strategy use multiple pings eg the server isn't there if it doesn't respond to 1/5 tries

sadly tcp has its timeout strategy and its ~50sec
0
 
gilad_noAuthor Commented:
I use a main server and a backup server. I've tried to ping each one of them 3 times with a 10 sec timeout for a single ping. Most of the times it works, if one of them don't responde, I use the second one, but rarely both of them don't responde to ping but they do responde to download: E.G: http connection. This is why I want to use the CAsyncSocket to connect, but how can I avoid the hang ? Why does the application hang ? Why it doesn't returns FALSE when I call Connect ?
0
 
ShaunWildeCommented:
because it is try to do the connect - it doesn't know your network is down especially if you have both modems and network cards in your machine - so it keeps trying until it times out intrnally did you try the Ioctl call ?
0
 
gilad_noAuthor Commented:
But I thought the CASyncSocket is already in non-blocking mode. Doesn't it ?
0
 
ShaunWildeCommented:
not from what I read it isn't only if you are dealing with dgrams and then it just sets up a default ip/port
0
 
gilad_noAuthor Commented:
So how can I check network connection before using it ?
I've tried the "IsNetworkAlive" function but it returns TRUE even when I pull out my cable. I don't want to use ping because it's not always reliable. What other thing can I do ?
0
 
ShaunWildeCommented:
you could try resolving ip addresses (if you do not have a local DNS server) and or pinging other known machines - alas I have never found a way of 100% reliability - you could also run the connection in a seperate thread - that way your UI does not hang - if you are using RAS you could test the status of modem connection eg enumerate the devices and see which are connected (whether it is Internet is another matter)
0
 
gilad_noAuthor Commented:
I don't have problems with modem, I do check RAS connection. But how can I check network ? How does ICQ nor Microsoft Messenger don't hang when trying to connect to network ?
0
 
ShaunWildeCommented:
> Microsoft Messenger don't hang when trying to connect to network

they probably do the connection in a seperate thread so the connecting phase does not affect the UI
0
 
gilad_noAuthor Commented:
But when I do it in a seperate thread, I can't close it.
How can I close it while waiting to connect. Can I use CAsyncSocket::ShutDown ?
0
 
ShaunWildeCommented:
> But when I do it in a seperate thread, I can't close it.

no but you can terminate the thread if necessary (eg app closedown) - or just ignore it and leave it to time out on its own
0
 
gilad_noAuthor Commented:
And if I terminate the thread, won't it cause memory leaks ?
0
 
ShaunWildeCommented:
> And if I terminate the thread, won't it cause memory leaks ?

yes but you would only termintae the thread if you app was closing down - so any memory leaks should get tidied up (unless they are system resources - eg GDI/Global Memory/BSTRs - otherwise I 'd just ignore the thread if I was no longer interested in its outcome. - you could terminate the socket from another thread it is only the MFC class that isn't thread safe not the handle
0
 
gilad_noAuthor Commented:
Thanks for all your help :)
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

  • 15
  • 11
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now