在我的应用中,我使用NSStreams
进行客户端服务器通信。事件delegate
中的hasbytesAvailable
方法在我读取数据时返回null
案例:当长度为4096时,读取失败并返回nil;意味着当长度等于缓冲区大小时它无法读取,即使我将maxlength设置为4000并且缓冲区大小为4096,那么每当读取4000个字节时它也会失败。该怎么办?
以下是代码:
case NSStreamEventHasBytesAvailable:
if (aStream == inputStream) {
uint8_t buffer[4096];
int len;
while ([inputStream hasBytesAvailable]) {
len = (int)[inputStream read:buffer maxLength:sizeof(buffer)];
NSLog(@"\nThe length is -- %d\n",len);
if (len > 0) {
NSData *data = [[NSData alloc] initWithBytes:buffer length:len];
output = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
// output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSUTF8StringEncoding];
}
}
}
NSLog(@"\n\n%@\n\n",output);
答案 0 :(得分:1)
从网络连接读取的数据并不总是以发送的相同大小的块接收。这意味着接收方需要:
正确执行此操作的最简单方法之一是在消息前加上字节数,然后只尝试从网络连接中读取那么多数据。这会在"网络缓冲区中留下任何剩余的数据"直到客户想要它。
您的代码正在接收一个字符串,该字符串将被NUL
终止,这意味着您需要以固定大小的块读取数据,检查每个字节,直到找到字符串结尾,然后在将块转换为字符串之前将块粘在一起。然后你需要记住任何"遗留的"下一条消息的数据。复杂的东西,嗯?
我会使用邮件大小前缀,因为这是其他人所做的事情。
答案 1 :(得分:0)
我认为代码绝对正常并且它应该读取数据,可能在您读取4096字节后可能有更多字节可用并且循环继续,并且您再次初始化输出变量,所以你可能会错过它。
使用以下代码段:
self.edgesForExtendedLayout = UIRectEdgeRight | UIRectEdgeLeft | UIRectEdgeBottom;