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检测,该方法用于同步等待任务完成或引发异常。因此,在您的场景中,如果StreamSockedDataReader.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

08-04 15:54