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();
}
答案 0 :(得分:1)
我如何才能找到StreamSocket是否已连接
我测试了你的代码。正如您所知,DataReader / DataWriter并不关心自己的“连接”。但是关闭的连接将由方法Task.Wait检测,该方法用于同步等待已完成的任务或抛出异常。因此,在您的方案中,如果StreamSocked
在DataReader.LoadAsync
之前关闭,taskLoad.AsTask().Wait(2000);
将抛出异常:
发生了一个或多个错误。 (远程主机强行关闭现有连接。)
如果在处理DataReader.LoadAsync
期间套接字连接关闭,则此时客户端无法检测到关闭,它将在下次客户端向服务器发送消息时检测到连接已关闭。在您的方案中,客户端将继续向服务器发送消息,这将始终在发送新消息时捕获连接关闭。如果服务器关闭连接,您将在await writer.StoreAsync();
代码行处获得连接关闭异常。
但是在5-6消息后,我的项目是手,我没找到错误在哪里
您可能已经捕获关于连接关闭的例外情况。所以这可能由其他一些原因导致。我看到你的代码片段中的DataReader
仅加载一次1024的长度消息。因此,如果从服务器发送的消息长于1024,则客户端将仅接收部分消息,并且下次当服务器发送新消息时,客户端仍将从上次收到保留消息而不是新消息。经过几次,服务器将返回记录许多数据,并可能导致问题。我建议您按如下方式更新reader.LoadAsync
代码:
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));
}
Addtionaly,我强烈建议您改为使用StreamReader,这不会像DataReader
那样受到关注,而您的ReadResponse()
方法可以简单如下:
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。