locked
Correct way to explicitly close a socket?

    Question

  • Hi 

    What is the correct way to close explicitly a stream/datagram socket in WinRT? Right now, I'm calling "delete socket;" to trigger the close (code borrowed from a socket sample on MSDN) but I have doubts (in C++ the Close method isn't exposed). Can't this cause a double "delete" of the object?

    The delete call is also sometime hanging with the following stack:

    > Windows.Networking.dll!StreamSocketConnectOperationServer::OnCancel() Line 190 C++
    Windows.Networking.dll!StreamSocketServer::Close() Line 633 C++
    hello.exe!Platform::IDisposable::<Dispose>() C++
    hello.exe!IceInternal::closeSocket(Platform::Object ^ fd) Line 906 C++
    hello.exe!IceInternal::StreamTransceiver::close() Line 139 C++

    If I put a break point in the StreamSocketConnectOperationServer::OnCancel method in the assembly code, I notice that the method is called over and over indicating that StreamSocketServer::Close is somehow stuck in some kind of infinite loop calling OnCancel (the process is also consuming 100% CPU when the hang starts). Could this be a bug in the WinRT socket implementation? Is there a better way to close a socket in C++?

    Thanks,

    Benoit.

    Wednesday, July 11, 2012 8:18 AM

All replies

  • (in C++ the Close method isn't exposed)

    Could you paste an example of how you are creating / using the socket? Close should be exposed, so I think I may be missing something.

    David Lamb

    Wednesday, July 11, 2012 7:35 PM
    Moderator
  • Hi David,

    The compiler gives me this error when trying to call Close on the socket:

        ..\Network.cpp(882) : error C2039: 'Close' : is not a member of 'Windows::Networking::Sockets::StreamSocket'

    I don't have a simple example but my code is not much different from the MSDN socket sample where you'll see that ScenarioInput4.xaml.cpp also uses delete as well instead of calling Close to close the socket.

    I find it surprising that calling delete on reference counted objects is allowed. Is this allowed by C++/CX?

    Benoit.

    Wednesday, July 18, 2012 7:46 AM
  • delete is allowed. It will invoke the destructor for the WinRT object. The behavior is documented here: Quick Reference (C++/CX).

    Delete is the documented way to close a StreamSocket in C++/CX. It is called out in the Remarks section for StreamSocket.Close | close method. It is a bit confusing that you close the socket differently depending on the language.


    David Lamb

    Wednesday, July 18, 2012 5:43 PM
    Moderator
  • It is indeed confusing and having to delete the socket to close it is not very intuitive! I suppose there is an internal mechanism to prevent the object to be destructed a second time when the number of references to it drop to zero.

    I'm afraid I still don't know why the delete was stuck in some kind of infinite loop then. Can you think of any reasons why StreamSocketServer::Close() would be stuck calling StreamSocketConnectOperationServer::OnCancel() in a loop?

    Benoit.

    Wednesday, July 18, 2012 7:34 PM
  • It would be very helpful if you could save a dump of the process in that problem state. In a cursory review I see one area it could loop, so I'd like to make sure there's not a bug you are exposing. Contact me via email for instructions on sending us a dumpfile: DavidLam At Microsoft Dot COM.

    Thanks!


    David Lamb

    Wednesday, July 18, 2012 8:06 PM
    Moderator
  • I'm wondering... who is spreading that plaque in MS where all kinds of quirks are stuffed right into the OS api?! Instead of making it absolutely clear and keeping Close() method in all languages, it uses delete... WTF is that?! Does it actually delete the internal object? or it just overloaded operator delete that doesn't actually do what this operator is normally is expected to do?
    Tuesday, October 21, 2014 11:30 PM