iOS NSStream套接字读取TCP不稳定并被截断
问题描述:
我正在使用以下代码从服务器套接字读取。一切都开始正常,但随着事情的进展,返回的数据会被截断并被错误地分块。我已经阅读了所有尝试不同的东西,例如更改缓冲区大小和同步代码,但仍然没有运气。起初我以为是因为iOS NSStream套接字读取TCP不稳定并被截断
-(void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent {
异步调用所以我试着同步它,但没有运气那里。我多次增加了缓冲区,但没有运气......我只希望从服务器读取一整行传递给messagedReceived的每次启动它。我确信我正在做一些愚蠢的事情,或者忽视某些对某些人来说显而易见的事情。
-(void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent {
switch (streamEvent) {
case NSStreamEventOpenCompleted:
DLog(@"Connection Opened!!!");
[delegate connectionOpened];
break;
case NSStreamEventHasBytesAvailable:
if (theStream == inputStream) {
uint8_t buffer[1024];
int len = 0;
while ([inputStream hasBytesAvailable]) {
len = [inputStream read:buffer maxLength:sizeof(buffer)];
if (len > 0) {
NSString *output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding];
if (nil != output) {
DLog(@"%@", output);
[self messageReceived:output];
}
}
}
}
break;
case NSStreamEventErrorOccurred:
DLog(@"Can not connect to the host!");
答
TCP流是正义的,字节流,它们本身不支持面向消息的和个人的网络数据包可能会被重组,拆分和随意合并。唯一能保证从头到尾的是所有的字节将按照它们发送的顺序到达。你需要自己处理缓冲部分行(或者更频繁的组合行),方法是将它们拆分为新行并保存部分结果。
答
那么我最终所做的只是寻找行结束字符本人和建设处理它。
-(void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent {
switch (streamEvent) {
case NSStreamEventOpenCompleted:
DLog(@"Connection Opened!!!");
[delegate connectionOpened];
break;
case NSStreamEventHasBytesAvailable:
if (theStream == inputStream) {
uint8_t buffer[1024];
int len = 0;
while ([inputStream hasBytesAvailable]) {
len = [inputStream read:buffer maxLength:sizeof(buffer)];
if (len > 0) {
NSString *output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding];
if (nil != output) {
if ([output rangeOfString:@"\n"].location == NSNotFound) {
line = AS(line, output);
} else {
NSArray *chunks = [output componentsSeparatedByString: @"\n"];
line = AS(line, chunks[0]);
[self messageReceived:line];
DLog("M: %@", line);
line = chunks[1];
}
}
}
}
}