处理WinRT StreamSocket断开连接(服务器端和客户端端)

我有一个我正在为Windows 8 / WinRT编写的应用程序,它使用StreamSocket API与服务器建立流连接。 也就是说,服务器将数据流式传输到客户端,有时使用元标记,并且可以随时断开连接。

我遇到的问题是我不知道如何检测服务器何时断开连接。 StreamSocket类(输入或输出流)或与连接状态有关的DataReader / DataWriter类似乎没有任何事件或属性。

最重要的是,在服务器端与客户端断开连接后,DataReader方法ReadAsync不会失败。 相反,操作成功,据我所知,它填充到缓冲区的数据只是服务器发送给它的最后一件事(即它没有清除它的内部缓冲区,即使我可以看到它已经“消耗”了每次调用ReadByte时缓冲区。 它为ReadAsync的每次后续调用执行此操作 – 使用服务器在断开连接之前发送的内容重新填充缓冲区。 这是代码的简化版本:

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 } else { while (dr.UnconsumedBufferLength > 0) { byte nextByte = dr.ReadByte(); // DriveStateMachine(nextByte); } } } } 

也就是说,服务器将数据流式传输到客户端,有时使用元标记,并且可以随时断开连接。 我遇到的问题是我不知道如何检测服务器何时断开连接。

另一方可以检测到“优雅”的套接字闭包为0长度读取。 也就是说,它只是像常规的流末端一样。

“流产”套接字关闭更棘手。 您必须发送数据以检测另一方已关闭,并且一旦写入失败,任何其他读取或写入都将失败(有例外)。 如果您的协议不允许您发送数据,那么您将不得不假设超时到期后连接错误并且只是关闭它。 🙁

根据应用程序“中止”套接字关闭可能是正常的 – 特别是,可能会编写非常繁忙的服务器来钳位关闭它们的连接,因为它允许它们更快地回收资源(避免步套接字关闭握手)。

StreamSocket类(输入或输出流)或与连接状态有关的DataReader / DataWriter类似乎没有任何事件或属性。

DataReader / DataWriter不关心“连接”。 他们真的只是BitConverter ,这次只设计得更好。

我猜想StreamSocket没有“连接”属性的原因是因为Socket.Connected几乎没用,而且肯定会产生误导 。


我会尝试直接使用StreamSocket.InputStream.ReadAsync而不是使用DataReader ,因为你只是在读取字节。 听起来你可能在DataReader发现了一个错误,如果InputStream.ReadAsync按预期工作,你应该在Microsoft Connect上报告。 另见相关论坛post 。