Обработка разъединений WinRT StreamSocket (как на стороне сервера, так и на стороне клиента)
У меня есть приложение, которое я пишу для Windows 8 / WinRT, использующее API StreamSocket для потокового соединения с сервером. То есть сервер передает данные клиенту, иногда с метатегами, и может в любой момент отключиться.
Проблема, с которой я столкнулся, заключается в том, что я понятия не имею, как определить, когда сервер отключился. Похоже, что нет никаких событий или свойств в классе StreamSocket, ни в его входных или выходных потоках, ни в классах DataReader / DataWriter, которые имеют какое-либо отношение к состоянию соединения.
Кроме того, метод DataReader ReadAsync не завершается сбоем после того, как серверная часть отключается от клиента. Вместо этого, насколько я могу судить, операция завершается успешно, и данные, которые она заполняет в своем буфере, - это просто последнее, что сервер отправил ему (т. Е. Он не очищает свой внутренний буфер, хотя я вижу, что он имеет & quot «потребляется» буфер каждый раз, когда я вызываю ReadByte). Он делает это для каждого последующего вызова ReadAsync - пополняя буфер тем, что сервер отправил последним, прежде чем он отключился. Вот упрощенная версия кода:
<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>