【问题标题】:NSInputStream getBuffer: length: doesn't work?NSInputStream getBuffer:长度:不起作用?
【发布时间】:2010-10-29 10:34:09
【问题描述】:

我真的很想使用 NSInputStream 的 getBuffer:length: 方法。 经过大量研究,我找不到使用此方法的有效示例,因为大多数人确实需要read: maxLength:

所以现在关于周围环境的一些事实: * 我正在为 iPhone 开发一个应用程序,iOS 3.1.3 * 我已经通过套接字建立了网络通信 * 该网络连接确实有效;所以我没有忘记向runloop或有效的委托或类似的东西添加一个流 - 它已经工作了 * 我只通过网络发送和接收字符串。 * 我设置了一个有效的委托,它正确地实现了stream: handleEvent:(区分接收到的事件并采取适当的措施)。 我不确定接收代码是否 100% 正确,因为我有时会收到两次消息。 这也可能是我正在与之通信的设备上的错误实现引起的。 为了弄清楚它是最后一个点中的哪一个,我试图找出当我收到“NSStreamEventHasBytesAvailable”事件时接收缓冲区上有多少字节。 因为我不确定我的实现是否正确,但我想知道我收到的实际字节数,我想使用getBuffer: length: 并在之后查看长度。 奇怪的是:长度从未打印在控制台上,因为 [((NSInputStream *) stream) getBuffer: &buf length: &numBytes] 总是评估为 FALSE。 无论如何,之后的代码部分可以正常工作,在缓冲区中接收消息并正确转发 - 工作正常。 问题仍然存在:为什么getBuffer: length: 不起作用? 感兴趣的代码在这里:

` 案例 NSStreamEventHasBytesAvailable: {

        uint8_t *buf;
        unsigned int numBytes;

        if ([((NSInputStream *) stream) getBuffer: &buf length: &numBytes]) {
            NSLog(@"\t\tBytes in the buffer: %i", &numBytes);
        }

        uint8_t buffer[BUFFER_SIZE];
        int len = [((NSInputStream *) stream) read: buffer 
                                         maxLength: BUFFER_SIZE];
        NSLog(@"\tread: %i bytes", len);

        /*
         if len > 0: len is equal to the filled byte elements
         if len == 0: end of buffer was reached while reading
         if len < 0: something terrible happened...
         */
        if (len > 0) {
            /* 1. create string from received byte buffer */
            NSString *msg = [[NSString alloc] initWithBytes: buffer length: len encoding: NSASCIIStringEncoding];
            NSLog(@"\tcontained message: %@", msg);
            /* 2. inform communicator about received message */
            [communicator received: msg];
            [msg release];
        }

        if (len < 0) {
            [communicator received: @"Error!"];
        }
        break;
    }

`

如果有人可以帮助我,那就太好了!

【问题讨论】:

    标签: objective-c nsinputstream


    【解决方案1】:

    达尔文是开源的,所以“真相就在那里”。 NSStream 的源代码显示 GSInetInputStream 是为套接字实现 NSInputStream 的类,而该类的 getBuffer:length: 实现简洁地回答了这个问题:

    - (BOOL) getBuffer: (uint8_t **)buffer length: (unsigned int *)len
    {
      return NO;
    }
    

    找到here

    【讨论】:

    【解决方案2】:

    我认为 getBuffer 不起作用,因为还没有缓冲区,之后您正在读取缓冲区,因此它还无法获取指向缓​​冲区的指针...

    【讨论】:

    • 没有意义,因为该代码仅在我收到“NSStreamEventHasBytesAvailable”事件时才会执行,因此底层缓冲区中有可用数据(我想通过调用 @ 987654321@。我刚刚将if getBuffer:length: 块移到read:maxLength: 块下方,正如预期的那样:没有任何改变
    • 进一步:我正在尝试从该缓冲区中读取而不是写入其中(我认为这就是您所说的“读入缓冲区”的意思?)。
    • 字节可用的事件并不意味着它们在缓冲区中,有字节准备好从流中读入缓冲区。假设您正在打开文件的流,当您打开流时,流中有可用字节可供读取,但尚未将任何文件读入缓冲区。 “读入缓冲区”是指通过流获取字节并将它们放入缓冲区。
    【解决方案3】:

    啊,我想我明白你的意思了。但我想至少在读入缓冲区之后,下面的代码应该评估为 TRUE? 我只是在问,因为它没有,getBuffer:length: 似乎仍然不起作用。 使用可用字节的通信效果很好,但问题仍然存在......

            uint8_t *buf1;
            unsigned int numBytes1;
            if ([((NSInputStream *) stream) getBuffer: &buf length: &numBytes]) {
                NSLog(@"\t\tBytes are in the buffer before Op.");
            }
    
            uint8_t buffer[BUFFER_SIZE];
            int len = [((NSInputStream *) stream) read: buffer 
                                             maxLength: BUFFER_SIZE];
    
            uint8_t *buf2;
            unsigned int numBytes2;
            if ([((NSInputStream *) stream) getBuffer: &buf2 length: &numBytes2]) {
                NSLog(@"\t\tBytes in the buffer after Op.");
            }
    

    很抱歉为我自己的问题创建了一个答案;但是注释能够处理这么多代码...

    【讨论】:

    • 如果将 numbytes 更改为 NSUInteger 而不是 "unsigned int" 会发生什么?
    • 缓冲区不可用,在 read: maxLength: 之前和之后都不可用。对我来说无关紧要,因为我在没有 getBuffer: length: 的情况下调试了我的应用程序的那一部分。谢谢你的时间,奥利弗!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-12
    • 2017-09-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多