datareader.loadAsync未检测到关闭的套接字(带有inputstreamOptions::Partial)
我正在通过TCP连接向服务器发送数据并读取响应,但之后一切都在这里工作。但在5-6条消息之后,我的项目就在手边,我没有找到错误的地方。
有一次我发现通过主机关闭了连接
那么,我如何才能发现streamsocket是否已连接
=代码=============
public async Task<bool> Connect(string host, string port)
{
try
{
socket = new StreamSocket();
HostName hostName = new HostName(host);
CancellationTokenSource _cts = new CancellationTokenSource();
_cts.CancelAfter(5000);
// Connect to the server
await socket.ConnectAsync(hostName, port).AsTask(_cts.Token);
return true;
}
catch (Exception ex)
{
throw ex;
}
}
public async Task<String> SendMessageToServer(string message)
{
try
{
// Create the data writer object backed by the in-memory stream.
using (writer = new DataWriter(socket.OutputStream))
{
writer.WriteString(message);
await writer.StoreAsync();
await writer.FlushAsync();
writer.DetachStream();
return await ReadResponse();
}
}
catch (Exception ex)
{
throw ex;
}
}
private async Task<String> ReadResponse()
{
DataReader reader;
StringBuilder strBuilder = new StringBuilder();
try
{
using (reader = new DataReader(socket.InputStream))
{
uint ReadBufferLength = 1024;
// If task cancellation was requested, comply
//cancellationToken.ThrowIfCancellationRequested();
// Set InputStreamOptions to complete the asynchronous reask(cancellationToken);
reader.InputStreamOptions = Windows.Storage.Streams.InputStreamOptions.Partial;
IAsyncOperation<uint> taskLoad = reader.LoadAsync(ReadBufferLength);
taskLoad.AsTask().Wait(2000);
string msg = string.Empty;
while (reader.UnconsumedBufferLength > 0)
{
strBuilder.Append(reader.ReadString(reader.UnconsumedBufferLength));
msg = strBuilder.ToString();
}
reader.DetachStream();
reader.Dispose();
}
}
catch (Exception ex)
{
return "0";
throw ex;
}
finally
{
// Cleanup once complete
}
return strBuilder.ToString();
}
最佳答案
我怎么能找到is streamsocket是否已连接
我在我这边测试了你的代码。datareader/datawriter与您所知道的“连接”本身无关。但关闭的连接将由方法Task.Wait检测,该方法用于同步等待任务完成或引发异常。因此,在您的场景中,如果StreamSocked
在DataReader.LoadAsync
之前关闭,则taskLoad.AsTask().Wait(2000);
将引发异常:
发生了一个或多个错误。(远程主机强制关闭了现有连接。)
如果在DataReader.LoadAsync
处理过程中关闭了套接字连接,则这次客户端无法检测到关闭,它将在下次客户端向服务器发送消息时检测到连接已关闭。在您的场景中,客户机将继续向服务器发送消息,在发送新消息时,服务器将始终捕获连接关闭。如果服务器关闭连接,您将在代码行的await writer.StoreAsync();
处得到连接关闭异常。
但是在5-6条消息之后,我的项目是手工的,我没有找到错误在哪里
您可能捕获了有关连接关闭的异常。因此,这可能是由其他一些原因导致的。我在代码片段中看到DataReader
只加载一次长度为1024的消息。因此,如果从服务器发送的消息超过1024,客户端将只接收部分消息,下次当服务器发送新消息时,客户端仍将从上一次而不是新消息接收剩余消息。几次之后,服务器将备份许多数据并可能导致问题。我建议您将代码更新如下:
string msg = string.Empty;
var loadsize = await reader.LoadAsync(ReadBufferLength);
while (loadsize >= ReadBufferLength)
{
loadsize = await reader.LoadAsync(ReadBufferLength);
}
if (reader.UnconsumedBufferLength > 0)
{
strBuilder.Append(reader.ReadString(reader.UnconsumedBufferLength));
}
另外,我强烈建议您使用StreamReader代替,它不会像
reader.LoadAsync
那样有问题,您的DataReader
方法可以简单如下:private async Task<String> ReadResponse()
{
Stream streamIn = socket.InputStream.AsStreamForRead();
StreamReader reader2 = new StreamReader(streamIn);
string response = await reader2.ReadLineAsync();
return response;
}
有关uwp中streamsocket的更多详细信息,请参考official sample。