如何使用DataReader从WinRT中的StreamSocket读取所有未知长度的数据

时间:2014-12-09 17:12:18

标签: sockets windows-runtime winjs winrt-async

我已将套接字配置为读取部分数据,如下所示:

@socket = new Windows.Networking.Sockets.StreamSocket()
hostName = new Windows.Networking.HostName(@ip)
@ensureConnection = @socket.connectAsync(hostName, @port.toString())
.then () =>
  @writer = new DataWriter(@socket.outputStream)
  @reader = new DataReader(@socket.inputStream)
  @reader.inputStreamOptions = InputStreamOptions.partial

然后我从套接字读取的函数如下所示:

readLineAsync = (reader, buffer = "") ->
while reader.unconsumedBufferLength
  byte = reader.readByte()
  if byte is 0
    return WinJS.Promise.as(buffer)
  buffer += String.fromCharCode(byte)
reader.loadAsync(1024).then (readBytes) ->
  if readBytes is 0
    WinJS.Promise.as(buffer)
  else
    while reader.unconsumedBufferLength
      byte = reader.readByte()
      if byte is 0
        return WinJS.Promise.as(buffer)
      buffer += String.fromCharCode(byte)
    readLineAsync(reader, buffer)

此功能有2个问题:

  1. 对于非常大的响应,堆栈会使用递归的readLineAsync调用进行构建。我怎么能防止这种情况?我是否应该使用WinJS Scheduler API或类似工具将下一次调用排队到readLineAsync

  2. 有时,当套接字上没有数据时,reader.loadAsync无法完成。有时确实如此,readByte则为0。那是为什么?

  3. 为什么我在该函数的2个位置上循环读取器的uncunsumedBufferLength?我最初在loadAsync延续处理程序中有这个代码。但由于响应可以包含终止\0 char,因此我需要在函数输入时检查读取器缓冲区中的未读数据。

    这是用于向套接字发送/接收的伪循环:

    readResponseAsync = (reader) ->
      return readLineAsync(@reader).then (line) ->
        result = parseLine(line)
        if result.unknown then return readResponseAsync(reader)
        return result
    
    @ensureConnection.then () =>
      sendCommand(...)
    
      readResponseAsync(@reader).then (response) ->
        # handle response
    

    来自MS的所有WinRT示例都处理套接字上的已知数据量,因此它们并不适合我的场景。

0 个答案:

没有答案