【问题标题】:In UWP StreamSocket, can I read data with timeout and leave the connection open if timeout elapses在 UWP StreamSocket 中,如果超时过去,我可以读取超时数据并保持连接打开吗
【发布时间】:2017-03-03 11:11:55
【问题描述】:

正如How to peek StreamSocket for data in UWP apps 所要求的那样,我找不到任何方法来窥视数据(读取数据而不消耗缓冲区),我现在正尝试自己“窥视”,但仍然没有运气。

我不知道如何以允许我使用超时并在超时过去时保持连接可用的方式从 StreamSocket 读取数据。

最后,问题如下。在我的,比方说,IMAP 客户端,我从服务器得到响应,如果这个响应是否定的,我需要稍等片刻,看看服务器是否立即发送另一个响应(有时,服务器可以做到这一点,有额外的细节在错误甚至零数据包上关闭连接)。如果服务器没有发送另一个响应,我很好,只是离开方法并返回给调用者。然后调用者可以向流中发送更多数据、接收更多响应等。

因此,在发送请求并获得初始响应后,在某些情况下,我需要以非常小的超时间隔再次读取套接字,如果没有数据到达,则什么都不做。

【问题讨论】:

    标签: sockets windows-runtime uwp winrt-async


    【解决方案1】:

    您可以使用CancelationTokenSource 生成超时并停止async 操作。 DataReader 使用来自StreamSocket 的输入流的数据。当至少有一个字节的数据时,它的LoadAsync() 方法将返回。在这里,我们添加了一个取消源,它将在 1 秒后取消异步任务以停止 DataReader.LoadAsync() 如果没有数据被消费。

    var stream      = new StreamSocket();
    
    var inputStream = stream.InputStream;
    
    var reader      = new DataReader(inputStream);
    reader.InputStreamOptions   = InputStreamOptions.Partial;
    
    while(true)
    {
        try
        {
            var timeoutSource   = new CancellationTokenSource(TimeSpan.FromSeconds(1));
            var data    = await reader.LoadAsync(1).AsTask(timeoutSource.Token);
    
            while(reader.UnconsumedBufferLength > 0)
            {
                var read    = reader.ReadUInt32();
            }
        }
        catch(TaskCanceledException)
        {
            // timeout
        }
    }
    

    不要忘记释放DataReader 将关闭流和连接。

    【讨论】:

    • 谢谢。但是,一旦 DataReader 完成工作,我该如何摆脱它呢?然后,我需要以与以前相同的状态将连接返回给调用者。理想情况下,我需要能够将其附加到现有连接并在连接生命周期内多次分离。
    • 您可以使用 DetachStream() 将 Stream 从阅读器中分离出来:docs.microsoft.com/en-us/uwp/api/…。这将允许您在处理阅读器时保持 Stream 打开。
    • 糟糕,在检查 DataReader 时,我发现我已经在我的其他代码中将它用于完全相同的目的,而且我似乎完全忘记了我之前已经解决了这个任务,只是几个月前..难以置信..
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-05
    • 1970-01-01
    • 1970-01-01
    • 2014-07-24
    • 1970-01-01
    • 1970-01-01
    • 2010-12-15
    相关资源
    最近更新 更多