Manejo de las desconexiones de WinRT StreamSocket (tanto del servidor como del lado del cliente)

Tengo una aplicación que estoy escribiendo para Windows 8 / WinRT que usa la API de StreamSocket para hacer una conexión de transmisión a un servidor. Es decir, el servidor transmite datos al cliente, a veces con etiquetas meta, y puede desconectarse en cualquier momento.

El problema que tengo es que no tengo idea de cómo detectar cuándo el servidor se ha desconectado. No parece haber ningún evento o propiedad en la clase StreamSocket, ni en sus flujos de entrada o salida, ni en las clases DataReader / DataWriter que tienen algo que ver con el estado de la conexión.

Además de eso, el método DataReader ReadAsync no está fallando después de que el servidor se desconecta del cliente. En su lugar, la operación se realiza correctamente por lo que puedo decir, y la información que llena en su búfer es solo la última cosa que el servidor le envió (es decir, no está borrando su búfer interno, aunque puedo ver que se ha "consumido") el búfer cada vez que llamo ReadByte). Hace esto por cada llamada subsiguiente a ReadAsync - rellenando el búfer con lo que el servidor envió por última vez antes de desconectarse. Aquí hay una versión simplificada del código:

<code>    public async Task TestSocketConnectionAsync()
    {
        var socket = new StreamSocket();
        await socket.ConnectAsync(new HostName(Host), Port.ToString(),
            SocketProtectionLevel.PlainSocket);
        var dr = new DataReader(socket.InputStream);
        dr.InputStreamOptions = InputStreamOptions.Partial;

        this.cts = new CancellationTokenSource();
        this.listenerOperation = StartListeningAsync(dr, cts);
    }

    public async Task StartListeningAsync(DataReader dr, CancellationTokenSource cts)
    {
        var token = cts.Token;
        while (true)
        {
            token.ThrowIfCancellationRequested();
            var readOperation = dr.LoadAsync(1024);
            var result = await readOperation;
            if (result <= 0 || readOperation.Status != Windows.Foundation.AsyncStatus.Completed)
            {
                cts.Cancel(); // never gets called, status is always Completed, result always > 0
            }
            else
            {
                while (dr.UnconsumedBufferLength > 0)
                {
                    byte nextByte = dr.ReadByte();

                    // DriveStateMachine(nextByte);
                }
            }
        }
    }
</code>

Respuestas a la pregunta(1)

Su respuesta a la pregunta