gpt4 book ai didi

c# - 如何在客户端检测关闭的 StreamSocket

转载 作者:可可西里 更新时间:2023-11-01 02:42:16 25 4
gpt4 key购买 nike

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();
}

最佳答案

How can i found that is StreamSocket is connected or not

我在我这边测试了你的代码。如您所知,DataReader/DataWriter 本身并不关心“连接”。但是关闭的连接将通过方法 Task.Wait 检测到,用于同步等待任务完成或抛出异常。因此,在您的场景中,如果 StreamSockedDataReader.LoadAsync 之前关闭, taskLoad.AsTask().Wait(2000); 将抛出异常:

One or more errors occurred. (An existing connection was forcibly closed by the remote host. )

如果套接字连接在DataReader.LoadAsync 处理期间关闭,此时客户端无法检测到关闭,它将在客户端下次向服务器发送消息时检测到连接关闭。在您的场景中,客户端将继续向服务器发送消息,服务器在发送新消息时将始终捕获连接关闭。如果服务器关闭连接,您将在 await writer.StoreAsync(); 代码行收到连接关闭异常。

But after 5-6 message my project is hand I didn't find where is error

您可能已经捕获了有关连接关闭的异常。所以这可能是由其他一些原因导致的。我在你的代码片段中看到 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));
}

此外,我强烈建议您使用 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 .

关于c# - 如何在客户端检测关闭的 StreamSocket,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40404185/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com