MFC CSocket Connect() hangs.

Posted on 2006-05-03
Last Modified: 2012-05-05
I'm having a problem with CSocket that I can't resolve, it seems easy enough and probably is but I'm completely stuck.
I have a server and a client application, the client contacts the server when it needs data, the data is sent using the MFC classes CFileSocket, CArchive and CSocket and the size of the data is between 10 KB and 2000 KB depending on what is requested.

The code snippet below shows where the problem is:

1      if (!socket.Create())
2            throw CMyException(_T("socket.Create"), socket.GetLastError());
4      if (!socket.Connect(server, port))            // HANGS!
5            throw CMyException(_T("socket.Connect"), socket.GetLastError());

The program doesn't always hang on row 4, usually it hangs after 2-3 requests, if I restart the server it works fine again.
Interestingly, if I put a breaktpoint on row 4 and wait a while or step into socket.Connect() everything works fine so it seems like there is some timing problem.
Another interesting thing I have noticed is that if I send small pieces of data the program doesn't hang, perhaps it will hang if I repeat the process many,many times but there is no indication of it as I far as I can tell.
Question by:Prambo
    LVL 32

    Accepted Solution

    In my opinion you should NEVER use a blocking Connect() call in your Windows application.  Connect() can hang indefinitely and you have no way of knowing if/when it might do so.

    My suggestion is to stop using the CSocket class altogether and redesign your application with CAsyncSocket instead.  Then if/when this happens you can wait for an appropriate period of time (5-10 sec), cancel the non-responding connect call and retry the connection.

    Yes, using async sockets is more complex but I assure you your users will appreciate the fact that your application will still be responsive when a connect/read/write operation on a socket hangs due to any number of reasons.
    LVL 1

    Author Comment

    The reason I use CSocket is that I don't want the complexity of CAsyncSocket because the request is serial by nature (i.e. Web request->COM->CSocket->Thread->CSocket). If I would use CAsyncSocket I would have to either poll for completion or implement the same functionality as in CSocket and nothing has been gained.
    I have thought about your suggestion before but have been too lazy to try it out but I'll give it a go.
    LVL 32

    Expert Comment

    No, you would not, and in fact, SHOULD NOT, poll for completion.  Your application should be designed to receive a notification message when the status of the socket changes.  If you poll you will end up with the same problem you have now, namely that the application will hang while waiting for the socket.

    And YES, MUCH is gained.  The specific problem you are having is solved as well as other problems that I've mentioned.

    LVL 1

    Author Comment

    I have solved the problem by using the CTimeOutSocket class as outlined in
    When the call hangs on Connect() it gets cancelled automatically after a set period of time and I retry, there haven't been any need to retry more than once on any instance.
    More or less the solution looks like:

    1     if (!socket.Create())
    2          throw CMyException(_T("socket.Create"), socket.GetLastError());
    4     socket.SetTimeOut(5*1000);
    4     if (!socket.Connect(server, port))
    5          throw CMyException(_T("socket.Connect"), socket.GetLastError());
    6     socket.KillTimeOut();

    The code above is wrapped inside a try-catch and do-while which repeats the Connect() call if the first call wasn't successful.
    The reason I didn't want to use CAsyncSocket in the first place is that I would have to rewrite a lot of code that was using CArchive and CSocketFile and that didn't appeal at all. I'll still award jhance all the points because I think his statement made me think about my solution in the first place and his solution would probably have worked if I had the time to change the main implementation.
    LVL 32

    Expert Comment

    There are problems, severe in my opinion, with this band-aid approach.
    LVL 1

    Author Comment

    The reason I gave a C is that the solution suggested is not what I asked for and something I already had considered. I did think about using the CTimeOutSocket class though after jhance's suggestion, to quote:  "Then if/when this happens you can wait for an appropriate period of time (5-10 sec), cancel the non-responding connect call and retry the connection", I do exactly as he suggests but using CTimeOutSocket instead of CAsyncSocket and therefore I rewarded him the points.
    To quote the grading criteria: "or if the answers, after clarification, lack finality or do not completely address the issue presented, then a "C" grade is an option".

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    How to run any project with ease

    Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
    - Combine task lists, docs, spreadsheets, and chat in one
    - View and edit from mobile/offline
    - Cut down on emails

    Suggested Solutions

    Here we come across an interesting topic of coding guidelines while designing automation test scripts. The scope of this article will not be limited to QTP but to an overall extent of using VB Scripting for automation projects. Introduction Now…
    Does the idea of dealing with bits scare or confuse you? Does it seem like a waste of time in an age where we all have terabytes of storage? If so, you're missing out on one of the core tools in every professional programmer's toolbox. Learn how to …
    Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …
    In this fifth video of the Xpdf series, we discuss and demonstrate the PDFdetach utility, which is able to list and, more importantly, extract attachments that are embedded in PDF files. It does this via a command line interface, making it suitable …

    760 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

    9 Experts available now in Live!

    Get 1:1 Help Now