I really would like to use the getBuffer:length:
method of an NSInputStream.
After a lot of research i couldn't find a valid example that uses this method, because most people really needed read: maxLength:
.
So now some facts on the surroundings:
* I'm developing an app for the iPhone, iOS 3.1.3
* I've established a network communication via sockets
* That network connection actually works; so i didn't forget to add a a stream to the runloop or a valid delegate or such things - it already works
* I'm only sending and receiving Strings over the network.
* I've set a valid delegate that implements stream: handleEvent:
correctly (differentiates between the received events and takes proper actions).
I'm not sure if the receiving code is 100% correct as i sometimes receive a message twice.
This could also be caused be a faulty implementation on the device i'm communicating with.
To figure out which of the last to points it is, i'm trying to find out how many bytes are really on the receiving buffer when i receive a开发者_运维百科 "NSStreamEventHasBytesAvailable" event.
As i don't know for sure that my implementation is correct, but i wanted to know the actual number of bytes i received, i wanted to use getBuffer: length:
and take a look at the length afterwards.
Strange thing is: the length is never printed on the console, as
[((NSInputStream *) stream) getBuffer: &buf length: &numBytes]
always evaluates to FALSE.
Anyway, the part of code afterwards works correctly, receives the message in the buffer and forwards it correctly - works good.
Question remains: Why doesn't getBuffer: length:
work?
The code of interest is here:
` case NSStreamEventHasBytesAvailable: {
uint8_t *buf;
unsigned int numBytes;
if ([((NSInputStream *) stream) getBuffer: &buf length: &numBytes]) {
NSLog(@"\t\tBytes in the buffer: %i", &numBytes);
}
uint8_t buffer[BUFFER_SIZE];
int len = [((NSInputStream *) stream) read: buffer
maxLength: BUFFER_SIZE];
NSLog(@"\tread: %i bytes", len);
/*
if len > 0: len is equal to the filled byte elements
if len == 0: end of buffer was reached while reading
if len < 0: something terrible happened...
*/
if (len > 0) {
/* 1. create string from received byte buffer */
NSString *msg = [[NSString alloc] initWithBytes: buffer length: len encoding: NSASCIIStringEncoding];
NSLog(@"\tcontained message: %@", msg);
/* 2. inform communicator about received message */
[communicator received: msg];
[msg release];
}
if (len < 0) {
[communicator received: @"Error!"];
}
break;
}
`
Would be nice if someone could help me!
Darwin is open source, so "the truth is out there". The source for NSStream shows that GSInetInputStream is the class that implements a NSInputStream for a socket, and the implementation of getBuffer:length: for that class answers the question succinctly:
- (BOOL) getBuffer: (uint8_t **)buffer length: (unsigned int *)len
{
return NO;
}
Found here.
I think that getBuffer isn't working because there isn't a buffer yet, you are reading into the buffer afterwards, so it cant get the pointer to the buffer yet...
ah, i think i get what you mean. but i suppose the following code should then evaluate to TRUE at least after reading into the buffer?
i'm just asking, because it doesn't, getBuffer:length:
still seems not to work.
the communication using the available bytes works well, but the question remains...
uint8_t *buf1;
unsigned int numBytes1;
if ([((NSInputStream *) stream) getBuffer: &buf length: &numBytes]) {
NSLog(@"\t\tBytes are in the buffer before Op.");
}
uint8_t buffer[BUFFER_SIZE];
int len = [((NSInputStream *) stream) read: buffer
maxLength: BUFFER_SIZE];
uint8_t *buf2;
unsigned int numBytes2;
if ([((NSInputStream *) stream) getBuffer: &buf2 length: &numBytes2]) {
NSLog(@"\t\tBytes in the buffer after Op.");
}
sorry for creating an answer to my own question; but the comment was able to handle so much code...
精彩评论