Solved

Network connection with CAsyncSocket

Posted on 2001-08-05
29
711 Views
Last Modified: 2013-11-20
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
Comment
Question by:gilad_no
  • 15
  • 11
  • 3
29 Comments
 
LVL 32

Expert Comment

by:jhance
ID: 6353004
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
 

Author Comment

by:gilad_no
ID: 6353023
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
 

Author Comment

by:gilad_no
ID: 6353036
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
 
LVL 32

Expert Comment

by:jhance
ID: 6353065
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
 

Author Comment

by:gilad_no
ID: 6353069
If I shut it down, would it return FALSE immediately ?
0
 

Author Comment

by:gilad_no
ID: 6353082
If I shut it down, would it return FALSE immediately ?
0
 

Author Comment

by:gilad_no
ID: 6353201
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
 
LVL 32

Expert Comment

by:jhance
ID: 6353704
The call to CASyncSocket::Connect should return to you immediately regardless of whether or not there is any connection made.

Show your code....
0
 
LVL 9

Expert Comment

by:ShaunWilde
ID: 6355591
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
 

Author Comment

by:gilad_no
ID: 6355663
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
 
LVL 9

Expert Comment

by:ShaunWilde
ID: 6356081
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
 
LVL 9

Expert Comment

by:ShaunWilde
ID: 6356121
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
 

Author Comment

by:gilad_no
ID: 6356220
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
 
LVL 9

Expert Comment

by:ShaunWilde
ID: 6356766
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
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

 

Author Comment

by:gilad_no
ID: 6358377
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
 
LVL 9

Expert Comment

by:ShaunWilde
ID: 6358503
> 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
 

Author Comment

by:gilad_no
ID: 6358751
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
 
LVL 9

Expert Comment

by:ShaunWilde
ID: 6360201
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
 

Author Comment

by:gilad_no
ID: 6360416
But I thought the CASyncSocket is already in non-blocking mode. Doesn't it ?
0
 
LVL 9

Expert Comment

by:ShaunWilde
ID: 6361232
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
 

Author Comment

by:gilad_no
ID: 6362913
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
 
LVL 9

Expert Comment

by:ShaunWilde
ID: 6362932
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
 

Author Comment

by:gilad_no
ID: 6362960
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
 
LVL 9

Expert Comment

by:ShaunWilde
ID: 6363971
> 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
 

Author Comment

by:gilad_no
ID: 6364032
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
 
LVL 9

Expert Comment

by:ShaunWilde
ID: 6364735
> 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
 

Author Comment

by:gilad_no
ID: 6366978
And if I terminate the thread, won't it cause memory leaks ?
0
 
LVL 9

Accepted Solution

by:
ShaunWilde earned 75 total points
ID: 6367672
> 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
 

Author Comment

by:gilad_no
ID: 6376987
Thanks for all your help :)
0

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

In this article, I'll describe -- and show pictures of -- some of the significant additions that have been made available to programmers in the MFC Feature Pack for Visual C++ 2008.  These same feature are in the MFC libraries that come with Visual …
Introduction: Finishing the grid – keyboard support for arrow keys to manoeuvre, entering the numbers.  The PreTranslateMessage function is to be used to intercept and respond to keyboard events. Continuing from the fourth article about sudoku. …
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
This video discusses moving either the default database or any database to a new volume.

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now