开发者

Opening a streaming connection to an HTTP server on iPhone/Cocoa environment?

开发者 https://www.devze.com 2023-01-01 12:28 出处:网络
I\'ve been using NSURLConnection to do a HTTP post to establish the connection.I\'ve also implemented the didReceiveData delegate to process incoming bytes as they become available.

I've been using NSURLConnection to do a HTTP post to establish the connection. I've also implemented the didReceiveData delegate to process incoming bytes as they become available.

As incoming data comes in via didReceiveData, I add the NSData to a data buffer and try parsing the bytesteam if enough data has come in to complete a message segment. I'm having a hard time managing the data buffer (NSMutableData object) to remove bytes that have been parsed to structs. Was curious if there's an easier way. My didReceiveData delegate is below.

It works, but I don't think I'm managing memory correctly after I copy the message segment (currMsg) out of the responseData buffer and call processMsg. I get double free errors when running under the Simulator -- the program doesn't crash.

NSMutableData/NSData provide methods for appending bytes to the end but I didn't see any methods for removing bytes from the beginning (bytes representing whats already bee开发者_高级运维n parsed. I would appreciate some advice on how to best remove the parsed bytes from the responseData buffer. I come from a mostly C background so I'm not sure if there are better ways of manipulating the NSData bytes pointer. I'd like to avoid copying if possible -- just want to process a portion of the responseData buffer and leave the rest in responseData for next time enough bytes are in it for parsing.

Thanks

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {

NSData *tmpBuffer = nil;
NSInteger currMsgSize = 10;

[responseData appendData:data];
NSInteger rspDataLen = [responseData length];

while(rspDataLen >= 10) {

    currMsg = [[NSData alloc] initWithBytesNoCopy:(void *)[responseData bytes] length:currMsgSize];

    [self processMsg:currMsg];

    [currMsg release];
    [responseData getBytes:tmpBuffer range:NSMakeRange(currMsgSize, rspDataLen - currMsgSize)];
    [responseData release];
    responseData = [[NSMutableData alloc] initWithBytesNoCopy:(void *)tmpBuffer length:rspDataLen - currMsgSize];
    rspDataLen = rspDataLen - currMsgSize;
}

}


Where do you allocate the first responseData?

What is [self processMsg:currMsg] doing with the data? If it is expecting the data to be around after -processMsg: returns, and it isn't explicitly making a copy, then you are in trouble.

Infact, unless you have finished with the received data before didReceiveData: returns, you need to make a copy of it somewhere, which isn't visible in the code shown.

You need to allocate the storage for tempBuffer, not pass in an uninitialised pointer;

You should look probably for a pre-rolled implementation of a simple ring buffer. There are plenty around.

0

精彩评论

暂无评论...
验证码 换一张
取 消