View Full Version : NSStream Send & Receive Handler
jasonjohnson
2005.09.28, 12:11 PM
Not being at all new to network programming, the concepts behind socket-level communication between hosts is familiar to me. The technical execution of this using NSStream, however, is a little fuzzy.
I am very interested in networked game-play, and am simply trying to understand the fundamentals of building this sort of thing using Cocoa and Objective-C.
The following is what I have pulled together out of some intensely complicated applications. It appears to do a little something, throwing off no errors and launching quickly and without fault.
How is it I modify this code to handle the actual acceptance of data? Are there any exceedingly simple examples I could reference? Any tips for organizing this kind of functionality? Am I completely lost and unaware of it? :)
- (IBAction)doSend:(id)sender
{
NSString * strHost = @"www.idevgames.com";
NSHost * objHost = [NSHost hostWithName:strHost];
int intPort = 80;
uint8_t buffer[1024];
[NSStream getStreamsToHost:objHost
port:intPort
inputStream:&receiveStream
outputStream:&sendStream];
[receiveStream retain];
[sendStream retain];
[receiveStream close];
[sendStream close];
}
Thanks!
Taxxodium
2005.09.28, 01:40 PM
Have you read this (http://developer.apple.com/documentation/Cocoa/Conceptual/Streams/index.html)?
jasonjohnson
2005.09.28, 03:30 PM
No, I have not read this -- though I will certainly do so now. I had been working off the documentation for the specific classes involved: NSStream (http://developer.apple.com/documentation/Cocoa/Reference/Foundation/ObjC_classic/Classes/NSStream.html), NSInputStream (http://developer.apple.com/documentation/Cocoa/Reference/Foundation/ObjC_classic/Classes/NSInputStream.html#//apple_ref/doc/uid/20001982), and NSOutputStream (http://developer.apple.com/documentation/Cocoa/Reference/Foundation/ObjC_classic/Classes/NSOutputStream.html#//apple_ref/doc/uid/20001983). I was not aware a conceptual overview existed.
When I am finished reading and have a working implementation of these classes, I will make sure and post the code for further scrutiny.
I certainly appreciate the link. Hopefully this will prove to be what I've been looking for. :)
jasonjohnson
2005.09.29, 12:14 PM
Nearly there. The article did help explain a few things. However, now that I have stream events firing properly, I'm looking for a more elegant way to write and read to and from the streams.
The "open" and "close" methods are tied to interface elements through a simple controller, and the stream event handler (like I mentioned above) seems to be doing its job very well. On each event, it's printing to the console.
Following the NSStreamEventOpenCompleted event of "sendStream", I attempted to write the beginnings of an HTTP request (per the example in the article), and yet when doing so, a socket error occurs and the request seems to be lost.
My question isn't regarding the troubleshooting of this particular issue - but rather - surely there is a simpler way to write to an open stream? Anyone have any suggestions? For that matter, is there an equally slick way to read from streams?
Mostly a style issue, but I just don't like how nasty this code could get.
Just FYI: I fully plan to develop two new methods for reading and writing, but for the moment, I am simply trying to get this to work. I do not want to introduce too much overhead and room for error during this exercise. I know the placement of this particular write to the sream is a little wonky :p
#import "Connection.h"
@implementation Connection
-(void) open: (NSString *) h : (int) p
{
strHost = h;
intPort = p;
[NSStream getStreamsToHost:objHost
port:intPort
inputStream:&receiveStream
outputStream:&sendStream];
[receiveStream retain];
[sendStream retain];
[receiveStream setDelegate:self];
[sendStream setDelegate:self];
[receiveStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[sendStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[receiveStream open];
[sendStream open];
printf("Open.\n");
}
- (void) stream: (NSStream *) stream handleEvent: (NSStreamEvent) eventCode
{
printf("EVENT: Start.\n");
switch(eventCode)
{
case NSStreamEventOpenCompleted:
{
printf("EVENT: Open completed.\n");
if(stream == receiveStream)
{
printf("Receiving...\n");
}
if(stream == sendStream)
{
printf("Sending...\n");
NSString * strBuffer = [NSString stringWithFormat:@"GET / HTTP/1.0\r\n\r\n"];
const uint8_t * rawstring = (const uint8_t *)[strBuffer UTF8String];
[sendStream write:rawstring maxLength:strlen(rawstring)];
}
break;
}
case NSStreamEventEndEncountered:
{
printf("EVENT: End encountered.\n");
break;
}
case NSStreamEventHasSpaceAvailable:
{
printf("EVENT: Has space available.\n");
break;
}
case NSStreamEventHasBytesAvailable:
{
printf("EVENT: Has bytes available.\n");
break;
}
case NSStreamEventErrorOccurred:
{
printf("EVENT: Error occurred.\n");
break;
}
case NSStreamEventNone:
{
printf("EVENT: None.\n");
break;
}
}
printf("EVENT: End.\n");
}
-(void) close
{
[receiveStream close];
[sendStream close];
printf("Closed.\n");
}
@end
vBulletin® v3.6.8, Copyright ©2000-2008, Jelsoft Enterprises Ltd.