首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >UWP应用程序的DataReader of SocketStream

UWP应用程序的DataReader of SocketStream
EN

Stack Overflow用户
提问于 2016-05-03 22:46:55
回答 1查看 3.1K关注 0票数 0

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

我正在连接到网络上的一些UPnP设备,这些设备通过端口1255将JSON发回。我有最初的连接工作和发送请求,告诉设备发送给我一些信息。

代码语言:javascript
复制
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循环周围旋转。如果比这个少,那么它只是坐在那里等待更多的数据。因此,缓冲区中可能有50个字节,我无法得到。在上面,inBufferCnt总是传递给LoadAsync的值的确切大小。

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

代码语言:javascript
复制
CancellationTokenSource cts = new CancellationTokenSource();
cts.CancelAfter(5000);
...
inBufferCnt = await reader.LoadAsync(64).AsTask(cts.Token);

我不知道我将从设备中得到多少数据,我对设备通信没有任何控制(除了请求信息)。我想我已经阅读了一半的网页,同时也在寻找解决方案,但我找不到任何与这个特定问题直接相关的东西。

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

救命..。

EN

回答 1

Stack Overflow用户

发布于 2016-05-06 08:37:41

我不知道我将从设备中得到多少数据,我对设备通信没有任何控制(除了请求信息)。因此,主要的问题是“您应该如何从套接字流读取,然后当没有更多的数据时(此时),只需返回当前流中的内容,缓冲区中可能还有任何大小等待读取。”

根据你的描述,我为你找到了一个解决办法:

首先,将输入流的读取选项设置为分部

代码语言:javascript
复制
reader.InputStreamOptions = Windows.Storage.Streams.InputStreamOptions.Partial;

通过这样做,当一个或多个字节可用时,异步读取操作将完成。因此,异步读取操作在没有任何字节可用的情况下,只等待新数据,然后添加一个超时来处理上述情况。

代码语言:javascript
复制
CancellationTokenSource cts = new CancellationTokenSource();
cts.CancelAfter(5000);
...
inBufferCnt = await reader.LoadAsync(sizeToReadEachTime).AsTask(cts.Token);

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

代码语言:javascript
复制
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;
}
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37015649

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档