我有一个正在为 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 || 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);
}
}
}
}