CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 9 of 9
  1. #1
    Join Date
    Nov 2011
    Posts
    72

    CAsyncSocket close problem

    Environment: windows XP and Win 7, Visual Studio 2008, MFC, C++, CAsyncSocket

    Setup: I wrote a test program that drives the server side and the client side of a TCP/IP connection using CAsyncSocket. It uses a C_Server class to listen for the client and accept the connection. That class creates an instance of the C_Server_Send object to send data to the client. It is working but is missing the proper closing function. I am working on fixing that. Now when the client closes the socket the C_Server_Send OnClose() is called. But I don’t know what to do here. The CAsyncSocket::Close does not appear to cause the object to delete itself. C_Server does not know that OnClose() has been called so the object that created this cannot delete it.

    Question:
    When the client closes the connection, what is the proper method to delete object CAsyncSocket?

    Question:
    In all the On*() overridden methods, should I load them up with error checking such as WSAGetLastError()?

    Note: If interested, I wrote up an article on this and posted it on codeproject.com here:
    http://www.codeproject.com/Articles/...84#xx4382684xx
    I have since realized that while it ends with error code zero, it still does not have proper closing code. That work is in progress. I discovered this as I started implementing my code in a real world application.
    Last edited by bkelly; November 6th, 2012 at 09:42 PM. Reason: typos

  2. #2
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,395

    Re: CAsyncSocket close problem

    Quote Originally Posted by bkelly View Post
    Question:
    When the client closes the connection, what is the proper method to delete object CAsyncSocket?
    What do you mean by "delete object CAsyncSocket"?

    Quote Originally Posted by bkelly View Post
    Question:
    In all the On*() overridden methods, should I load them up with error checking such as WSAGetLastError()?
    It usually depends upon what you are doing in these overrides.
    In OnAccept, for example, you first have to check the most recent error on a socket which is passed in this override.
    Victor Nijegorodov

  3. #3
    Join Date
    Nov 2011
    Posts
    72

    Re: CAsyncSocket close problem

    Quote Originally Posted by VictorN View Post
    What do you mean by "delete object CAsyncSocket"?

    It usually depends upon what you are doing in these overrides.
    In OnAccept, for example, you first have to check the most recent error on a socket which is passed in this override.
    Class C_Server posts the listen and when the client solicits a connection the accept() method creates an instance of C_Server_Send to carry on the conversation with the client. That object is newed on the heap and must be deleted.

    Regarding the overrides for On*(), none of them have an argument so I don't understand the phrase "... on a socket which is passed in this override." The word "passed" useally refers to items in the argument list.

  4. #4
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,395

    Re: CAsyncSocket close problem

    Quote Originally Posted by bkelly View Post
    Class C_Server posts the listen and when the client solicits a connection the accept() method creates an instance of C_Server_Send to carry on the conversation with the client. That object is newed on the heap and must be deleted.
    So, can't you delete it after closing the socket?

    Nd, BTW, there is a great article about using CAsyncSocket class in multithreaded client and server applications: An MFC Asynchronous Socket Example Done Right

    Quote Originally Posted by bkelly View Post
    Regarding the overrides for On*(), none of them have an argument so I don't understand the phrase "... on a socket which is passed in this override." The word "passed" useally refers to items in the argument list.
    Well, from MSDN:
    CAsyncSocket::OnAccept
    Called by the framework to notify a listening socket that it can accept pending connection requests by calling the Accept member function.

    Code:
    virtual void OnAccept(
       int nErrorCode 
    );
    ....

    CAsyncSocket::OnConnect
    Called by the framework to notify this connecting socket that its connection attempt is completed, whether successfully or in error.

    Code:
     virtual void OnConnect(
       int nErrorCode 
    );
    ....
    Victor Nijegorodov

  5. #5
    Join Date
    Nov 2011
    Posts
    72

    Re: CAsyncSocket close problem

    Hello Victor,
    Re: So, can't you delete it after closing the socket?

    The problem is not that I cannot delete it. The problem is what deletes it and when?

    Class C_Server, derived from CAsyncSocket, listens on a port and detects the client request to connect. In its Accept() method it creates a new object from class C_Server_Send, derived from CAsyncSocket, and that object carries on the conversation with the client. There is only one instance of C_Server, and it can service an undefined number of clients, creating multiple objects of type C_Server_Send. Once that object is created, to my knowledge, S_Server really has nothing more to do with the server / client conversation.

    When the client closes the connection, and if C_Server_Send has a read posted, method OnClose() of C_Server_Send is called. C_Server_Send can terminate communications and perform the Close() method. However, that does not delete the object.

    C_Server is unaware that the client has disconnected. Since C_Server_Send does not delete itself, how should it be deleted?

    I could add a function call to C_Server that C_Server_Send uses to state that it needs to be deleted, maybe passing in its "this" pointer. But I am suspecting that Microsoft handled this problem in another manner. That manner is the source of my query.

    Regarding the Done Right article, I have looked at it, but it seems to skip right over the asynchronous server description. Maybe I missed it. I will look again.

    Thank you for taking the time to reply.
    Last edited by bkelly; November 7th, 2012 at 09:32 AM. Reason: typos

  6. #6
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,395

    Re: CAsyncSocket close problem

    Quote Originally Posted by bkelly View Post
    When the client closes the connection, and if C_Server_Send has a read posted, method OnClose() of C_Server_Send is called. C_Server_Send can terminate communications and perform the Close() method. However, that does not delete the object.
    Maybe you could perform something like
    Code:
    void C_Server_Send::OnClose(int nErrorCode) 
    {
    	//	socket is to close due to other side demand
    	if(m_hSocket != INVALID_SOCKET)
    		ShutDown(both);
    	CAsyncSocket::Close();
    
    	CAsyncSocket::OnClose(nErrorCode);
    	delete this;
    }
    Note that I never used such a code myself (just because I create a new thread for every new connection, thus do NOT new the socket object and instead create in in stack in the corresponding thread) and am not sure it is not dirty.
    Victor Nijegorodov

  7. #7
    Join Date
    Nov 2011
    Posts
    72

    Re: CAsyncSocket close problem

    The use of "delete this" might work, I'll try it.

    I don't know how to create new threads and how to very efficiently pass data between them. (This application creates about ten TCP packets per millisecond and there can be three or four instances running at one time. It processes telemetry data.) If you know of a nice tutorial that explains those topics I can be convinced to make changes.

    I am currently using blocking code but while it works, it eventually causes some problems that asynch code will resolve.

    I am hoping that someone very familiar with CAsyncSocket will jump in.

    Thanks for taking the time to post.
    Last edited by bkelly; November 7th, 2012 at 10:00 AM. Reason: typo

  8. #8
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,395

    Re: CAsyncSocket close problem

    Quote Originally Posted by bkelly View Post
    I don't know how to create new threads and how to very efficiently pass data between them.
    Then you should check out the article I referred to!
    Note that I had implemented almost the same (well, I'd rather say not the same but very similar!) "algorithm" that was described in this article, and it worked in the old VC++6.0 applications and still works in my VS2010 applications.
    Victor Nijegorodov

  9. #9
    Join Date
    Nov 2011
    Posts
    72

    Re: CAsyncSocket close problem

    Ok. but that is a real heavy weight class. My application does nothing but send one type of data and never receives anything. And it does it ten times per millisecond so I want something as simple as possible, not a general purpose application. Still, I will look again for the technique.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured