C# 如何在客户端检测关闭的StreamSocket
DataReader.LoadAsync未检测到关闭的套接字(使用InputStreamOptions::Partial) 我通过TCP连接将数据发送到服务器并读取响应,但之后一切都在这里工作。但在收到5-6条信息后,我的项目已完成,我没有找到错误所在 有一段时间,我发现连接是通过主机关闭的 因此我如何才能找到is StreamSocket是否连接 =============代码=======================C# 如何在客户端检测关闭的StreamSocket,c#,tcp,uwp,C#,Tcp,Uwp,DataReader.LoadAsync未检测到关闭的套接字(使用InputStreamOptions::Partial) 我通过TCP连接将数据发送到服务器并读取响应,但之后一切都在这里工作。但在收到5-6条信息后,我的项目已完成,我没有找到错误所在 有一段时间,我发现连接是通过主机关闭的 因此我如何才能找到is StreamSocket是否连接 =============代码======================= public async Task<bool> Conne
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();
}
公共异步任务连接(字符串主机、字符串端口)
{
尝试
{
套接字=新的StreamSocket();
主机名=新主机名(主机);
CancellationTokenSource _cts=新的CancellationTokenSource();
_取消后的cts(5000);
//连接到服务器
等待socket.ConnectAsync(主机名、端口).AsTask(_cts.Token);
返回true;
}
捕获(例外情况除外)
{
掷骰子;
}
}
公共异步任务SendMessageToServer(字符串消息)
{
尝试
{
//创建内存中流支持的数据写入器对象。
使用(writer=newdatawriter(socket.OutputStream))
{
writer.WriteString(消息);
等待writer.StoreAsync();
等待writer.FlushAsync();
writer.DetachStream();
return wait ReadResponse();
}
}
捕获(例外情况除外)
{
掷骰子;
}
}
专用异步任务ReadResponse()
{
数据阅读器;
StringBuilder strBuilder=新StringBuilder();
尝试
{
使用(reader=newdatareader(socket.InputStream))
{
uint ReadBufferLength=1024;
//如果要求取消任务,请遵守
//cancellationToken.ThrowIfCancellationRequested();
//设置InputStreamOptions以完成异步请求(cancellationToken);
reader.InputStreamOptions=Windows.Storage.Streams.InputStreamOptions.Partial;
IAsyncOperation taskLoad=reader.LoadAsync(ReadBufferLength);
taskLoad.AsTask().Wait(2000);
string msg=string.Empty;
而(reader.unsumedBufferLength>0)
{
追加(reader.ReadString(reader.UnsumedBufferLength));
msg=strBuilder.ToString();
}
reader.DetachStream();
reader.Dispose();
}
}
捕获(例外情况除外)
{
返回“0”;
掷骰子;
}
最后
{
//清理完成后
}
返回strBuilder.ToString();
}
如何找到是否连接了StreamSocket
我在我这边测试了你的代码。DataReader/DataWriter并不关心您所知道的“连接”。但关闭的连接将由方法检测,该方法用于同步等待任务完成或引发异常。因此,在您的场景中,如果之前关闭了streamsocketd
,则taskLoad.AsTask().Wait(2000)代码>将引发异常:
发生了一个或多个错误。(远程主机强制关闭了现有连接。)
如果套接字连接在处理DataReader.LoadAsync期间关闭,则这次客户端无法检测到关闭,它将在客户端下次向服务器发送消息时检测到连接关闭。在您的场景中,客户端将继续向服务器发送消息,服务器在发送新消息时将始终捕获连接关闭。您将在await writer.StoreAsync()处收到连接关闭异常如果服务器关闭连接,则代码>代码行
但在5-6的消息之后,我的项目是手工的,我没有找到哪里有错误
您可能已捕获到有关连接关闭的异常。因此,这可能是由其他一些原因导致的。我在您的代码片段中看到了DataReader
,仅加载长度为1024的消息一次。因此,如果从服务器发送的消息长度超过1024,客户端将只接收部分消息,下次服务器发送新消息时,客户端仍将接收上次发送的剩余消息,而不是新消息。几次之后,服务器将备份许多数据,并可能导致问题。我建议您更新阅读器.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));
}
private async Task<String> ReadResponse()
{
Stream streamIn = socket.InputStream.AsStreamForRead();
StreamReader reader2 = new StreamReader(streamIn);
string response = await reader2.ReadLineAsync();
return response;
}
另外,我强烈建议您改用它,它不会像DataReader
那样令人担忧,您的ReadResponse()
方法可以简单如下:
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));
}
private async Task<String> ReadResponse()
{
Stream streamIn = socket.InputStream.AsStreamForRead();
StreamReader reader2 = new StreamReader(streamIn);
string response = await reader2.ReadLineAsync();
return response;
}
private async Task ReadResponse()
{
streamIn=socket.InputStream.AsStreamForRead();
StreamReader reader2=新的StreamReader(streamIn);
string response=wait reader2.readlinesync();
返回响应;
}
有关uwp中StreamSocket的更多详细信息,请参考