NSinputstream 读取数据返回空值?
NSinputstream read data is returning null value?
在我的应用程序中,我使用 NSStreams
进行客户端服务器通信。在事件 hasbytesAvailable
的 delegate
方法中,当我读取数据时返回 null
案例:当长度为4096时读取失败,returns nil;意味着当长度等于缓冲区大小时读取失败,即使我将最大长度设置为 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);
从网络连接读取的数据不会总是以与发送时相同大小的块接收。这意味着接收方需要:
- 准确了解消息中预期的数据量。
- 记住当前消息中的所有 "left over" 数据,因为它们属于下一条消息。
正确执行此操作的最简单方法之一是在消息前加上字节计数,然后仅尝试从网络连接中读取那么多的数据。这会将所有剩余数据留在 "network buffer" 中,直到客户需要它。
您的代码正在接收一个字符串,该字符串将以 NUL
结尾,这意味着您需要以固定大小的块读取数据,检查每个字节,直到找到字符串结尾然后将块拼接在一起,然后再将其转换为字符串。然后您需要记住下一条消息的所有 "left over" 数据。复杂的东西,嗯?
我会使用消息大小前缀,因为其他人几乎都是这样做的。
我认为代码绝对没问题,它应该读取数据,可能是在你读取了 4096 字节之后,可能还有更多字节可用,循环继续,你正在再次初始化输出变量,所以你可能漏掉了。
使用以下代码段:
if (aStream == inputStream) {
uint8_t buffer[4096];
int len;
NSString* tempOutput = @"";
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];
tempOutput = [tempOutput stringByAppendingString:output];
// output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSUTF8StringEncoding];
}
}
output = tempOutput;
}
在我的应用程序中,我使用 NSStreams
进行客户端服务器通信。在事件 hasbytesAvailable
的 delegate
方法中,当我读取数据时返回 null
案例:当长度为4096时读取失败,returns nil;意味着当长度等于缓冲区大小时读取失败,即使我将最大长度设置为 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);
从网络连接读取的数据不会总是以与发送时相同大小的块接收。这意味着接收方需要:
- 准确了解消息中预期的数据量。
- 记住当前消息中的所有 "left over" 数据,因为它们属于下一条消息。
正确执行此操作的最简单方法之一是在消息前加上字节计数,然后仅尝试从网络连接中读取那么多的数据。这会将所有剩余数据留在 "network buffer" 中,直到客户需要它。
您的代码正在接收一个字符串,该字符串将以 NUL
结尾,这意味着您需要以固定大小的块读取数据,检查每个字节,直到找到字符串结尾然后将块拼接在一起,然后再将其转换为字符串。然后您需要记住下一条消息的所有 "left over" 数据。复杂的东西,嗯?
我会使用消息大小前缀,因为其他人几乎都是这样做的。
我认为代码绝对没问题,它应该读取数据,可能是在你读取了 4096 字节之后,可能还有更多字节可用,循环继续,你正在再次初始化输出变量,所以你可能漏掉了。
使用以下代码段:
if (aStream == inputStream) {
uint8_t buffer[4096];
int len;
NSString* tempOutput = @"";
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];
tempOutput = [tempOutput stringByAppendingString:output];
// output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSUTF8StringEncoding];
}
}
output = tempOutput;
}