NSInputStream 没有收到所有数据
NSInputStream not receive all data
当我从服务器接收数据时出现错误(数据只是字符串)。
例如
服务器发送的数据(15000 字节)
我的 iPhone 收到数据(7878 字节)
所以我尝试搜索,我知道方法是答案。
但我无法应用我的代码..
我猜 NSMutableData 是提示..
怎么做..
这是我的代码。
- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent {
NSLog(@"stream event %lu", (unsigned long)streamEvent);
switch (streamEvent) {
case NSStreamEventOpenCompleted:
NSLog(@"Stream opened");
if(_connectServer)
{
[_connectServer invalidate];
_connectServer = nil;
}
break;
case NSStreamEventHasBytesAvailable:
if (theStream == inputStream)
{
if(!_serverOpen)
{
uint8_t buffer[1024];
int len;
while ([inputStream hasBytesAvailable])
{
len = (int)[inputStream read:buffer maxLength:sizeof(buffer)];
if (len > 0)
{
NSString *output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSUTF8StringEncoding];
if (nil != output)
{
[self receivedServerData:output];
if(!_serverOpen)
{
[self initNetworkCommunicationWithIpPort:output];
}
}
}
}
}
else
{
uint8_t buffer[20];
int len;
while ([inputStream hasBytesAvailable])
{
len = (int)[inputStream read:buffer maxLength:sizeof(buffer)];
NSString* strBuffer = [[NSString alloc] initWithBytes:buffer length:len encoding:NSUTF8StringEncoding];
NSLog(@"STRBUFFER %@", strBuffer);
strBuffer = [strBuffer substringFromIndex:7];
uint8_t dataBuffer[[strBuffer intValue]];
NSLog(@"databuffer %lu", sizeof(dataBuffer));
int lenBuffer = [inputStream read:dataBuffer maxLength:sizeof(dataBuffer)];
NSLog(@"lenBuffer %d", lenBuffer);
int position = 0 ;
if (lenBuffer > 0)
{
NSString *output = [[NSString alloc] initWithBytes:dataBuffer length:lenBuffer encoding:NSUTF8StringEncoding];
if (nil != output)
{
[self receivedServerData:output];
if(!_serverOpen)
{
[self initNetworkCommunicationWithIpPort:output];
}
}
}
}
}
}
else
{
NSLog(@"333");
}
break;
case NSStreamEventHasSpaceAvailable:
{
}
break;
case NSStreamEventErrorOccurred:
NSLog(@"Can not connect to the host!");
_serverOpen = NO;
break;
case NSStreamEventEndEncountered:
[theStream close];
[theStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
theStream = nil;
break;
default:
NSLog(@"Unknown event");
}
}
如果您可以访问发送数据的服务器,最简单的方法是将前 4 个字节设置为 int
,代表数据的长度。然后解析数据中的前 4 个字节并读取长度。然后,当输入流上有 space 可用时,一旦你有了长度,就继续将字节附加到 NSMutableData
属性,直到接收者有你在开始时得到的 length
。一旦完成,然后立即将其转换为字符串。由于网络延迟问题,您无法确定是否会立即在流中接收到所有数据。
正如@Manav 所述,您可以期望以多个块的形式接收流,只需将每个块附加到 NSMutableData,直到获得 NSStreamEventEndEncountered
.
当我从服务器接收数据时出现错误(数据只是字符串)。
例如
服务器发送的数据(15000 字节)
我的 iPhone 收到数据(7878 字节)
所以我尝试搜索,我知道方法是答案。
但我无法应用我的代码..
我猜 NSMutableData 是提示..
怎么做..
这是我的代码。
- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent {
NSLog(@"stream event %lu", (unsigned long)streamEvent);
switch (streamEvent) {
case NSStreamEventOpenCompleted:
NSLog(@"Stream opened");
if(_connectServer)
{
[_connectServer invalidate];
_connectServer = nil;
}
break;
case NSStreamEventHasBytesAvailable:
if (theStream == inputStream)
{
if(!_serverOpen)
{
uint8_t buffer[1024];
int len;
while ([inputStream hasBytesAvailable])
{
len = (int)[inputStream read:buffer maxLength:sizeof(buffer)];
if (len > 0)
{
NSString *output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSUTF8StringEncoding];
if (nil != output)
{
[self receivedServerData:output];
if(!_serverOpen)
{
[self initNetworkCommunicationWithIpPort:output];
}
}
}
}
}
else
{
uint8_t buffer[20];
int len;
while ([inputStream hasBytesAvailable])
{
len = (int)[inputStream read:buffer maxLength:sizeof(buffer)];
NSString* strBuffer = [[NSString alloc] initWithBytes:buffer length:len encoding:NSUTF8StringEncoding];
NSLog(@"STRBUFFER %@", strBuffer);
strBuffer = [strBuffer substringFromIndex:7];
uint8_t dataBuffer[[strBuffer intValue]];
NSLog(@"databuffer %lu", sizeof(dataBuffer));
int lenBuffer = [inputStream read:dataBuffer maxLength:sizeof(dataBuffer)];
NSLog(@"lenBuffer %d", lenBuffer);
int position = 0 ;
if (lenBuffer > 0)
{
NSString *output = [[NSString alloc] initWithBytes:dataBuffer length:lenBuffer encoding:NSUTF8StringEncoding];
if (nil != output)
{
[self receivedServerData:output];
if(!_serverOpen)
{
[self initNetworkCommunicationWithIpPort:output];
}
}
}
}
}
}
else
{
NSLog(@"333");
}
break;
case NSStreamEventHasSpaceAvailable:
{
}
break;
case NSStreamEventErrorOccurred:
NSLog(@"Can not connect to the host!");
_serverOpen = NO;
break;
case NSStreamEventEndEncountered:
[theStream close];
[theStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
theStream = nil;
break;
default:
NSLog(@"Unknown event");
}
}
如果您可以访问发送数据的服务器,最简单的方法是将前 4 个字节设置为 int
,代表数据的长度。然后解析数据中的前 4 个字节并读取长度。然后,当输入流上有 space 可用时,一旦你有了长度,就继续将字节附加到 NSMutableData
属性,直到接收者有你在开始时得到的 length
。一旦完成,然后立即将其转换为字符串。由于网络延迟问题,您无法确定是否会立即在流中接收到所有数据。
正如@Manav 所述,您可以期望以多个块的形式接收流,只需将每个块附加到 NSMutableData,直到获得 NSStreamEventEndEncountered
.