来自服务器的 iOS tcp 套接字 json

标签 ios objective-c tcp

在我的应用程序中,我打开一个到我的服务器的 TCP 套接字连接,然后等待数据。我的服务器以 JSON 格式发送所有数据,从服务器发送的消息可能如下所示:

{\"type\":\"message\", \"msg\": \"\", \"visitorNick\": \"nickName\", \"customField1\": \"\", \"visitorNick\": \"Visitor " + obj.channel + "\", \"time\": \"" + getDateTime() + "\", \"channel\": \"" + obj.channel + "\"}\n

在我的应用程序中,我正在使用运行循环来阅读:

- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent {


    switch (streamEvent) {

        case NSStreamEventOpenCompleted:
            NSLog(@"Stream opened");

            break;
        case NSStreamEventHasBytesAvailable:



            if (theStream == inputStream) {


                uint8_t buffer[1024];
                int len;
                NSMutableData *output = [[NSMutableData alloc] initWithLength:0];
                while ([inputStream hasBytesAvailable]) {
                    len = [inputStream read:buffer maxLength:sizeof(buffer)];
                    if (len > 0) {
                        [output appendBytes: (const void *)buffer length:len];
                    }
                }

                NSString *outputData = [[NSString alloc] initWithData:output encoding:NSUTF8StringEncoding];

                outputData = [outputData stringByReplacingOccurrencesOfString:@"\n" withString:@" "];
                outputData = [outputData stringByReplacingOccurrencesOfString:@"} {"
                                                     withString:@"} , {"];



                NSLog(@"RECIEVED ----------------------> %@", outputData);

                // Parse the message and add it to the right method
                NSError* error;
                NSDictionary *JSON =
                [NSJSONSerialization JSONObjectWithData: [outputData dataUsingEncoding:NSUTF8StringEncoding]
                                                options: NSJSONReadingMutableContainers
                                                  error: &error];


                NSString* type = [JSON objectForKey:@"type"];

                if(error) {
                    NSLog(@"PARSE ERROR ------------->>>>> : %@\n", error);
                }

                NSLog(@"SERVER TYPE --> %@\n", type);

                if([type isEqualToString:@"message"]) {
                    //NSLog(@"New chat message: %@", output);

                    [self messageReceived:outputData];

                }

            }
            break;


        case NSStreamEventErrorOccurred:

            NSLog(@"Can not connect to the host!");
            isConnected = 0;

            [[NSNotificationCenter defaultCenter] postNotificationName:@"showReconnect" object:nil];
            [NSThread sleepForTimeInterval:3.06];
            [self initNetworkCommunication];

            break;

        case NSStreamEventEndEncountered:

            [theStream close];
            [theStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
            NSLog(@"STREAM PAUSED");
            theStream = nil;

            break;

    }
}

我希望 \n 强制应用程序一次读取一个 JSON(例如,在 java 中,\n 用作刷新,因此一条消息一次读取)。现在,该应用有时会一次读取多个 JSON。

我认为问题出在这里:

            uint8_t buffer[1024];
            int len;
            NSMutableData *output = [[NSMutableData alloc] initWithLength:0];
            while ([inputStream hasBytesAvailable]) {
                len = [inputStream read:buffer maxLength:sizeof(buffer)];
                if (len > 0) {
                    [output appendBytes: (const void *)buffer length:len];
                }
            }

但我不确定如何强制应用一次只从服务器读取一个 JSON。

有什么想法吗?

最佳答案

如果每个 JSON block 在一行上发送,并且各行之间用换行符分隔 字符,您可以执行以下操作:

  • 将属性(或实例变量)NSMutableData *collectedData 添加到您的类中。
  • 情况下 NSStreamEventOpenCompleted: 初始化收集的数据:

    collectedData = [NSMutableData data];
    
  • case NSStreamEventHasBytesAvailable: 中,将所有接收到的数据附加到 收集的数据。然后检查是否有换行符。在这种情况下,提取 行(从开始到换行符)到一个单独的 NSData 对象 并将其从收集的数据中删除。这可能类似于以下(未经测试的)代码:

    NSData *nl = [@"\n" dataUsingEncoding:NSUTF8StringEncoding];
    
    uint8_t buffer[1024];
    int len;
    while ([inputStream hasBytesAvailable]) {
        len = [inputStream read:buffer maxLength:sizeof(buffer)];
        [collectedData appendBytes: (const void *)buffer length:len];
    }
    NSRange nlRange =[collectedData rangeOfData:nl options:0 range:NSMakeRange(0, [collectedData length])];
    while (nlRange.location != NSNotFound) {
        // Extract data from the beginning up to (but not including) the newline character:
        NSData *jsonData = [collectedData subdataWithRange:NSMakeRange(0, nlRange.location)];
        // Remove data from the beginning up to and including the newline character:
        [collectedData replaceBytesInRange:NSMakeRange(0, nlRange.location + nlRange.length) withBytes:NULL length:0];
    
        // Process jsonData ...
        NSError *error;
        NSMutableDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error];
        // ...
    
        // Check for another newline character:
        nlRange =[collectedData rangeOfData:nl options:0 range:NSMakeRange(0, [collectedData length])];
    }
    

关于来自服务器的 iOS tcp 套接字 json,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21202122/

相关文章:

ios - 使用 GLKit 绘图

ios Sprite 套件 bodyWithBodies 不工作

ios - 如何将值从一个 View 传递到 iOS 中的另一个 View ?

objective-c - 学习 Objective-C 的好资源

objective-c - Objective C 初始值设定项的命名约定?

Linux 3.0 TCP 堆栈接收缓冲区内核架构

java - 关闭 TCP 线程服务器

ios - CNContactViewController 取消按钮不起作用

objective-c - -DNDEBUG 和 -DNS_BLOCK_ASSERTIONS 标志有什么区别

sockets - 如何通过端口关闭 TCP 连接?