在我的应用程序中,我打开一个到我的服务器的 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/