【问题标题】:Read InputStream asynchronously异步读取 InputStream
【发布时间】:2016-02-21 13:37:55
【问题描述】:

我正在尝试接收数据包,如果没有收到任何字节,请继续使用下面的代码。 await ReadAsync 阻塞,直到收到新的数据包。有什么方法可以只读取当前接收到的字节吗?

如果我不使用 await 则不会收到消息。

byte[] data = new byte[BufferSize];

IInputStream inputStream = socket.InputStream;
IBuffer buffer = data.AsBuffer();

socketInformation.GetStopwatchPingIdleTime().Start();

while (socketInformation.open)
{
    try
    {
        inputStream.ReadAsync(buffer, BufferSize, InputStreamOptions.Partial);
        data = buffer.ToArray();
    }
    catch (Exception)
    {
        break;
    }

    while (true)
    {
        // Wait for payload size
        if (buffer.Length >= 4)
        {
            int commandType = (int)BitConverter.ToInt16(data, 0);
            int payloadSize = (int)BitConverter.ToInt16(data, 2);
            int packetSize = PacketHeaderSize + payloadSize;

            // Wait for a full message
            if (buffer.Length >= packetSize)
            {
                byte[] packet = new byte[packetSize];
                System.Buffer.BlockCopy(data, 0, packet, 0, packetSize);

                ParsePacketSequence(socket, socketInformation, packet);

                if (buffer.Length > packetSize)
                {
                    int bufferLength = (int)buffer.Length - packetSize;

                    byte[] newData = new byte[BufferSize];
                    System.Buffer.BlockCopy(data, packetSize, newData, 0, bufferLength);
                    data = newData;

                    buffer.Length = (uint)bufferLength;
                }
                else if (buffer.Length == packetSize)
                {
                    break;
                }
                else
                {
                    break;
                }
            }
            else if (buffer.Length == packetSize)
            {
                break;
            }
        }
        else
        {
            break;
        }
    }

    if (host)
    {
        // Send ping to player
        if (socketInformation.waitingPong == false && 
            socketInformation.GetStopwatchPingIdleTime().ElapsedMilliseconds > 5000)
        {
            byte[] pingPacket = CreatePacket(6, null);
            SendPacket(socket, socketInformation, pingPacket);

            socketInformation.waitingPong = true;
        }
    }

    await Task.Delay(33, tokenSource.Token);
}

inputStream.Dispose();
socket.Dispose();
tokenSource.Cancel();

【问题讨论】:

  • 这种做法很成问题。我什至不知道如何修复它。您能否详细说明您想要完成的工作,以便我们推荐不同的方法?
  • 例如没有办法“清空流”。在您声明它为空后一毫秒,可能会到达一个新字节。
  • @usr 我想检查是否有可读取的字节,如果没有,请继续循环并在循环重新启动时再次检查。
  • 所以我假设您想阅读一条消息?如果消息的第一个字节到达,其余的在 10 秒后到达怎么办?那你想做什么?

标签: c# inputstream


【解决方案1】:

在我看来,您正在接收消息流。当消息存在时,您可能希望在稍后的某个时间或在代码中的不同位置对其进行处理。

一种好的方法是让Task 不断地从套接字读取消息并将它们放入队列中。然后,您可以随时从队列中提取完整的消息。

这样你就可以摆脱这里的大部分逻辑。您永远不必中止读取请求,也永远不需要检查超时。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-11
    • 1970-01-01
    • 1970-01-01
    • 2010-11-18
    • 2010-12-20
    • 1970-01-01
    • 2012-03-03
    相关资源
    最近更新 更多