使用AsyncSocket进行不一致的读取行为

时间:2013-04-13 22:47:11

标签: ios rubymotion cocoaasyncsocket

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

ID 252第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部分:您好,这是测试版 ID 780第0部分:您好,这是一个测试字符串。 ID 419第0部分:您好,这是一个测试字符串。 ID 128第0部分:您好,这是一个测试字符串。 ID 638第0部分:您好,这是一个测试字符串。 ID 950第0部分:您好,这是一个测试字符串。 ID 950第1部分:字符串。 ID 704第0部分:您好,这是一个测试字符串。

正如您在阅读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) 然后它连接,但我的委托方法根本不起作用,数据似乎也没有发送。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

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