1

我正在使用 GCDAsyncSocket 编写一个 RubyMotion 应用程序,并且在将数据读取到特定术语(在我的情况下为 CRLF)时遇到不一致的结果。它有时会读取多个 CRLF 序列,而不是总是向上读取直到并包括下一个 CRLF。这本身不一定是问题,我可以拆分字符串并解析它,但是它有时会在后续字符串的中途读取,因此似乎会发生一些数据丢失。这似乎只发生在快速接收数据时。这是一个输出示例。我发送了字符串“你好,这是一个测试字符串。” 从服务器到我的应用程序快速连续 100 次。正如您从下面的代码中看到的那样,我将字符串拆分为 \r\n,为该特定读取调用分配一个随机数并打印出结果数组的每个部分(0、1、2 等)。

ID 252 Part 0:你好,这是一个测试字符串。ID 252 第 1 部分:您好,这是一个测试字符串。ID 252 第 2 部分:您好,这是一个测试字符串。ID 252 第 3 部分:您好,这是一个测试字符串。ID 252 第 4 部分:您好,这是一个测试字符串。ID 252 第 5 部分:您好,这是一个测试字符串。ID 252 第 6 部分:您好,这是一个测试字符串。ID 252 第 7 部分:您好,这是一个测试字符串。ID 252 第 8 部分:您好,这是一个测试 st ID 780 第 0 部分:您好,这是一个测试字符串。ID 419 Part 0:你好,这是一个测试字符串。ID 128 Part 0:你好,这是一个测试字符串。ID 638 Part 0:你好,这是一个测试字符串。ID 950 Part 0:你好,这是一个测试字符串。ID 950 第 1 部分:字符串。ID 704 Part 0:你好,这是一个测试字符串。

正如您在 read 950 中看到的那样,肯定会发生一些损失。这是我的代码的相关位。

def connect()
    $term = AsyncSocket.CRLFData
    clear_keybindings("")
    @ts = AsyncSocket.alloc.initWithDelegate(self, delegateQueue:Dispatch::Queue.main)
    @ts.connectToHost('...', onPort:4001, error:nil)
end

def onSocket(sock, didConnectToHost:host, port:port)
    $connected = true
    send_message('os ios')
    read_line
end

def onSocket(sock, didReadData:data, withTag:tag)
    read_line
    line = NSString.stringWithUTF8String(data.bytes)
    if !line
        return
    end
    id = Random.rand(1000)
    line.split("\r\n").each_with_index do |l, i|
        puts "ID #{id} Part #{i}: #{l}"
        parse(l)
    end
end

def read_line
    @ts.readDataToData($term, withTimeout:-1, tag:0)
end

当我写这篇文章时,我想知道使用 GCDAsyncSocket 是否可以解决这个问题,但如果我改变它:@ts = GCDAsyncSocket.alloc.initWithDelegate(self, delegateQueue:Dispatch::Queue.main) 那么它会连接,但是我的委托方法根本不起作用,似乎也没有发送数据。任何帮助,将不胜感激。

4

1 回答 1

0

我会把你的read_line电话移到didReadData:withTag:委托方法的最后。如果您在短时间内收到大量数据,则您可能在委托方法有机会完成其当前数据的处理之前读取新数据。

于 2013-10-27T22:11:54.233 回答