locked
StreamSocket Client gracious shutdown of TCP connection

    Question

  • I am working on Windows Store Application using StreamSocket in C++.

    When using StreamSocket on a client, I would like to graciously shutdown the TCP socket i.e. it should do the FIN-ACK-FIN-ACK handshake between the client and server (ofcourse the client is starting the socket teardown procedure).

    Unfortunately the current methods (that I could come across) always sends TCP RESET, which is not the right way. Can anyone point me to the right way of tearing down a TCP connection?

    Thanks a lot in advance.

    --Gopu

    Monday, November 12, 2012 10:36 PM

Answers

  • The local app can explicitly wait for a read to complete with zero bytes (this is dependent on remote app sending FIN),  then post no more reads*. The socket closure is then guaranteed to be graceful.

    *Technically, after a zero bytes completed read, all subsequent reads posted on the socket will also complete immediately with zero bytes. 

    When there is a pending read (recv), the close will always be abortive. This is same behavior for both Winsock and WinRT sockets.

    WinRT sockets does not support cancellation of pending reads on a socket. Even if it was supported, it would not result in graceful closure anyways – the pending read would just be completed with a different error (cancelled instead of aborted).  This is also the same behavior as Winsock.

    • Marked as answer by Jesse Jiang Friday, December 07, 2012 5:36 AM
    Tuesday, November 27, 2012 7:28 PM

All replies

  • I found out what was going wrong - I had a LoadAsync that was waiting for data, when I closed the connection.

    What I am trying to do is have a "select" function and "recv" function. Hence I need to have a LoadAsync waiting for data and it sets up a flag when data gets ready, so that the select function can inform that that particular socket is ready for reading.

    I did try using DataReaderLoadOperation's Close and Cancel methods - still I get TCP RESET.

    Can anyone please let me know how I can cancel this pending LoadAsync operation without sending a TCP RESET.

    In short, what's the difference between DataReaderLoadOperation.Close and DataReaderLoadOperation.Cancel? I would assume that DataReaderLoadOperation.Close would stop the LoadAsync operation without sending anything to the peer and DataReaderLoadOperation.Cancel would stop the LoadAsync operation by sending a TCP RESET to the peer.

    Please help me out here! Thank You

    Thursday, November 15, 2012 6:06 PM
  • more info...

    Looks like while LoadAsync is active, I can't do a DataReaderLoadOperation.Close (get an exception of illegal use) though I can use DataReaderLoadOperation.Cancel which immediately sends a TCP RST.

    Thursday, November 15, 2012 9:09 PM
  • The local app can explicitly wait for a read to complete with zero bytes (this is dependent on remote app sending FIN),  then post no more reads*. The socket closure is then guaranteed to be graceful.

    *Technically, after a zero bytes completed read, all subsequent reads posted on the socket will also complete immediately with zero bytes. 

    When there is a pending read (recv), the close will always be abortive. This is same behavior for both Winsock and WinRT sockets.

    WinRT sockets does not support cancellation of pending reads on a socket. Even if it was supported, it would not result in graceful closure anyways – the pending read would just be completed with a different error (cancelled instead of aborted).  This is also the same behavior as Winsock.

    • Marked as answer by Jesse Jiang Friday, December 07, 2012 5:36 AM
    Tuesday, November 27, 2012 7:28 PM
  • Thank You Vandana for the reply.

    My app is the client, hence it cannot wait to read zero byte since the client is supposed to send the FIN first.

    I am more familiar with UNIX sockets, though feel that Winsock is quite similar. We would call select to figure out if data is present in the socket to read and not call "recv" directly which would block (assuming a blocking socket).

    I have to read ahead to mimic the select behavior, hence wished there was a mechanism to cancel the LoadAsync operation gracefully.

    If you can think of any way please let me know - or if I need to make a request for such a feature, please guide me.

    Thanks again.

    --Gopu

    Wednesday, November 28, 2012 10:48 PM