UWP App SocketStream的DataReader [英] DataReader of SocketStream for UWP App

查看:42
本文介绍了UWP App SocketStream的DataReader的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我看到过一些与此类似的问题,但到目前为止我还没有看到适用于 UWP 平台的实际解决方案.

I've seen a few questions similar to this, but so far I've not seen an actual solution that works for the UWP platform.

我正在连接到网络上的一些 UPnP 设备,这些设备通过端口 1255 将 JSON 发回.我的初始连接正常,并且发送请求告诉设备向我发送一些信息.

I'm connecting to some UPnP devices on the network, which send JSON back over port 1255. I have the initial connection working and the send request that tells the devices to send me some info.

StreamSocket socket;
using (socket = new StreamSocket())
{
    hostName = new HostName("192.168.0.nnn");
    await socket.ConnectAsync(hostName, "1255");
    //Code that does the request for info
    await this.read();
}

public async Task<String> read()
{
    string runStr = "";
    uint inBufferCnt = 0;

    using (reader = new DataReader(socket.InputStream))
    {
        reader.InputStreamOptions = Windows.Storage.Streams.InputStreamOptions.ReadAhead;
        reader.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf8;
        reader.ByteOrder = Windows.Storage.Streams.ByteOrder.LittleEndian;

        inBufferCnt = await reader.LoadAsync(256); //InBuffer is always 256, 
            //even if there is more data waiting. If I put a task.delay in it will always return 256

        while (reader.UnconsumedBufferLength > 0)
        {
            var iRead = reader.ReadString(reader.UnconsumedBufferLength);
            runStr = runStr + iRead;
            inBufferCnt = await reader.LoadAsync(64); //always hangs here. 
                //Even if I reduce to 1, it will sit waiting for new data
        }
...

一切正常,直到最后一次 LoadAsync.当流中有数据时,只要它小于 64 字节,它就会围绕 While 循环旋转.如果少于这个 tho,那么它只是坐在那里等待更多的数据.所以缓冲区中可能有 50 个字节是我无法掌握的.在上面的 inBufferCnt 始终是传递给 LoadAsync 的值的确切大小.

Everything is working fine, up till the last LoadAsync. While there is data in the stream, then as long as it's less than 64 bytes then it'll spin back around the While loop. If there is less than this tho, then it just sits there waiting for more data. So there could be 50 bytes sat in the buffer that I can't get hold of. In the above the inBufferCnt is always the exact size of the value passed to LoadAsync.

我一直在尝试各种事情,例如添加超时,但是在触发异常后我无法访问任何有用的东西,所以我仍然不知道流中有多少数据.

I've been trying various things, such as adding a timeout, but I can't access anything of use after the exception is triggered, so I still don't know how much data is in the stream.

CancellationTokenSource cts = new CancellationTokenSource();
cts.CancelAfter(5000);
...
inBufferCnt = await reader.LoadAsync(64).AsTask(cts.Token);

我不知道我将从设备返回多少数据,我无法控制设备通信(除了请求信息).我想我在寻找解决方案时已经阅读了一半的网页,但我找不到与此特定问题直接相关的任何内容.

I have no idea how much data I will get back from the device, I have no control whatsoever over the device communication (Other than to request info). I think I've read half of the web while looking for a solution, but I can't find anything that relates directly to this specific issue.

所以主要问题是你应该如何从套接字流中读取,然后当没有更多数据时(此时),只返回当前流中的内容.可能还有任何大小等待读取的缓冲区.

So the main question is "How are you supposed to read from the socket stream and then when there is no more data (at this time), just return what is sitting in the current stream. There could be any size left in the buffer waiting to be read.

帮助...

推荐答案

我不知道我将从设备返回多少数据,我无法控制设备通信(除了请求信息).所以主要问题是你应该如何从套接字流中读取,然后当没有更多数据时(此时),只返回当前流中的内容.缓冲区中可能有任何大小的剩余等待待读.

I have no idea how much data I will get back from the device, I have no control whatsoever over the device communication (Other than to request info). So the main question is "How are you supposed to read from the socket stream and then when there is no more data (at this time), just return what is sitting in the current stream. There could be any size left in the buffer waiting to be read.

根据您的描述,我已经为您找到了解决方案:

According to your description, I have found a solution for you:

首先,设置阅读选项用于部分的输入流.

First, set the read options for the input stream to Partial.

reader.InputStreamOptions = Windows.Storage.Streams.InputStreamOptions.Partial;

通过这样做,异步读取操作在一个或多个字节可用时完成.因此,异步读取操作等待新数据没有任何可用字节时,然后您可以添加超时来处理上面提到的这种情况.

By doing this, the asynchronous read operation completes when one or more bytes is available. So the asynchronous read operation sits and waits for new data only when there is no any bytes is available, then you can add a timeout to handle this situation as you have mentioned above.

CancellationTokenSource cts = new CancellationTokenSource();
cts.CancelAfter(5000);
...
inBufferCnt = await reader.LoadAsync(sizeToReadEachTime).AsTask(cts.Token);

以下是我验证过的示例代码:

Following is the sample code I’ve verified:

public async Task<String> read()
{
    string runStr = "";
    uint inBufferCnt = 0;
    //size of bytes to load each time.
    uint sizeToReadEachTime = 256;
    CancellationTokenSource cts = new CancellationTokenSource();
    //set timeout here.
    cts.CancelAfter(5000);

    using (reader = new DataReader(socket.InputStream))
    {
        //set the read options for the input stream to Partial.
        reader.InputStreamOptions = Windows.Storage.Streams.InputStreamOptions.Partial;
        reader.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf8;
        reader.ByteOrder = Windows.Storage.Streams.ByteOrder.LittleEndian;

        while (true)
        {
            try
            {
                //add a timeout for the asynchronous load operation.
                inBufferCnt = await reader.LoadAsync(sizeToReadEachTime).AsTask(cts.Token);
                runStr += reader.ReadString(inBufferCnt);
            }
            catch (System.Threading.Tasks.TaskCanceledException)
            {
                //load operation will get timeout only when there is no data available.
                cts.Dispose();
                break;
            }
        }

        reader.DetachStream();
    }
    return runStr;
}

这篇关于UWP App SocketStream的DataReader的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆