hasBytesAvailable提前完成

时间:2017-01-09 00:01:41

标签: objective-c json sockets cocoa nsstream

我将JSON从我的服务器发送到我的cocoa应用程序。

cocoa应用程序接收如下数据:

case NSStreamEventHasBytesAvailable:
    NSLog(@"begin");
    if (theStream == inputStream) {
        int len;
        uint8_t buffer[4096];
        NSString* incoming_message = @"";
        while ([inputStream hasBytesAvailable]) {
            len = (int)[inputStream read:buffer maxLength:sizeof(buffer)];
            NSLog(@"\nThe length is -- %d\n",len);
            if (len > 0) {
                NSString *mess = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding];
                if(mess != nil){
                    incoming_message = [NSString stringWithFormat:@"%@%@",incoming_message,mess];
                }
            }
        }

        NSLog(@"%@",incoming_message);

        // handle icoming message
        [self handleIncomingNotification:incoming_message];
    }
    NSLog(@"end");

    break;

问题是,如果数据开始大于500个字符,它会分成两个(beginend日志被调用两次)所以handleIncomingNotification:会这样做因为它传递了一半的JSON而无法正常工作。

当我记录len时,我得到1448很多,有时1479,然后是4096

很明显hasBytesAvailable不能正常工作。

我尝试过更改缓冲区但没有区别。

请帮我想办法解决这个问题。我很惊讶这不是一个简单的谷歌。

从xaphod的回答编辑

我最终这样做了:

case NSStreamEventHasBytesAvailable:
    NSLog(@"begin");
    if (theStream == inputStream) {
        int len;
        uint8_t buffer[1024];
        NSString* incoming_message = @"";
        while ([inputStream hasBytesAvailable]) {
            len = (int)[inputStream read:buffer maxLength:sizeof(buffer)];
            if (len > 0) {
                NSString *mess = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding];
                    incoming_message = [NSString stringWithFormat:@"%@%@",incoming_message,mess];
            }
        }

        [self handleStreamMessage:incoming_message];
    }
    NSLog(@"end");

    break;

handleStreamMessage:

NSString*split_message;
-(void)handleStreamMessage:(NSString*)message{
    if(split_message == NULL){
        split_message = @"";
    }else if([split_message length] > 0){
        message = [NSString stringWithFormat:@"%@%@",split_message,message];
    }
    NSLog(@"message:%@",message);
    NSError *error;
    NSData* data = [message dataUsingEncoding:NSUTF8StringEncoding];
    if ([NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error] == nil)
    {
        // not finished the stream as not given proper json data
        split_message = message;
    }else{
        [self handleIncomingNotification:message];
        split_message = @"";
    }
}

这似乎是一个非常糟糕的黑客行为。

1 个答案:

答案 0 :(得分:2)

这不是NSStream网络流的工作方式。如果你发送X个字节,接收器将收到一定数量的N次,总共将(最终)为X.N可能是1,7或42 - 取决于多个事物。

您需要做的是解析JSON的内容,并确定何时完成接收以使其有意义。查看YAJLParser,我使用它来完成twitter api。让我给你一个链接...

..我的叉子在这里:https://github.com/xaphod/yajl-objc