User login

Navigation

Sponsor

Will It Blend? iPhone App
You Tube sensation Will It Blend? has been viewed over 1 million times. These beloved videos are now available in their very own iPhone app. Available in the appstore. More info can be found at www.iblendr.com

  1. /* The following is a brief class outline containing only the code needed to
  2. set up and publish a NSNetService for Bonjour networking
  3.  
  4. I've left some NSLog calls, some of which are commented out, for use in debugging
  5. problems when getting up and running, or making sure we have what we expect*/
  6.  
  7. #import <Foundation/Foundation.h>
  8. #import <netinet/in.h>
  9. #import <sys/socket.h>
  10.  
  11. #define CM_NET_DOMAIN (@"local.")
  12. #define CM_NET_TYPE (@"_netclass._tcp")
  13.  
  14. @interface NetClass : NSObject {
  15.  
  16. // net service stuff
  17. NSNetService *myService;
  18. NSSocketPort *netSocket;
  19. NSFileHandle *socketHandle;
  20. NSFileHandle *readHandle;
  21. struct sockaddr *socketAddr;
  22. int sPort;
  23.  
  24. }
  25.  
  26. // service communication methods
  27. -(BOOL) establishNetService;
  28. -(void) acceptConnection:(NSNotification*) n;
  29. -(void) readData:(NSNotification*) notification;
  30.  
  31. // NSNetService delegate methods
  32. -(void) netService:(NSNetService*) sender didNotPublish:(NSDictionary*) errorDict;
  33. -(void) netServiceDidPublish:(NSNetService*) sender;
  34. -(void) netServiceWillPublish:(NSNetService*) sender;
  35.  
  36. @end
  37.  
  38. @implementation NetClass
  39.  
  40. -(id) init {
  41. if(self = [super init]) {
  42. // set up the net service
  43. services = [[NSMutableArray alloc] init];
  44. BOOL go = [self establishNetService];
  45. if(!go) {
  46. // deal with error here...
  47. }
  48. // sign up for notifications when the file handle accepts a connection
  49. [[NSNotificationCenter defaultCenter] addObserver:self
  50. selector:@selector(acceptConnection:)
  51. name:NSFileHandleConnectionAcceptedNotification object:nil];
  52. // sign up for notifications that data is available to be read from the file handle
  53. [[NSNotificationCenter defaultCenter] addObserver:self
  54. selector:@selector(readData:)
  55. name:NSFileHandleDataAvailableNotification object:nil];
  56. }
  57.  
  58. return self;
  59. }
  60.  
  61. // establish our net service and publish it
  62. -(BOOL) establishNetService {
  63. // set up the port, let the system assign a port number
  64. netSocket = [[NSSocketPort alloc] initWithTCPPort:0];
  65. if(!netSocket) {
  66. NSLog(@"Unable to establish listening socket port...");
  67. return NO;
  68. }
  69.  
  70. // set up the net service
  71. socketAddr = (struct sockaddr*)[[netSocket address] bytes];
  72. if(socketAddr->sa_family == AF_INET) {
  73. sPort = ntohs(((struct sockaddr_in *)socketAddr)->sin_port);
  74. }
  75. else if(socketAddr->sa_family == AF_INET6) {
  76. sPort = ntohs(((struct sockaddr_in6 *)socketAddr)->sin6_port);
  77. }
  78. else {
  79. NSLog(@"Socket Family neither IPv4 or IPv6, can't handle...");
  80. return NO;
  81. }
  82.  
  83. // make sure we have a valid port and our socket is good, then publish
  84. if(netSocket && sPort) {
  85. //NSLog(@"got socket and port, getting ready to publish...");
  86. //NSLog(@"domain: \"%@\"",CM_NET_DOMAIN);
  87. //NSLog(@"type: \"%@\"",CM_NET_TYPE);
  88. netService = [[NSNetService alloc] initWithDomain:CM_NET_DOMAIN
  89. type:CM_NET_TYPE
  90. name:@""
  91. port:sPort];
  92. if(netService) {
  93. //NSLog(@"publishing service with name \"%@\"", [netService name]);
  94. [netService setDelegate:self];
  95. [netService publish];
  96. return YES;
  97. }
  98. else {
  99. //NSLog(@"Error establishing Net Service...");
  100. return NO;
  101. }
  102. }
  103.  
  104. // if we're here, something bad happened
  105. NSLog(@"Something bad happened setting up net service...");
  106. return NO;
  107. }
  108.  
  109. // accecpt a connection from the file handle
  110. -(void) acceptConnection:(NSNotification*) n {
  111. NSLog(@"Got a connection");
  112. readHandle = [[[n userInfo] objectForKey:NSFileHandleNotificationFileHandleItem] retain];
  113.  
  114. [readHandle waitForDataInBackgroundAndNotify];
  115. }
  116.  
  117. // read the data we've been waiting for on the connection
  118. -(void) readData:(NSNotification*) n {
  119. NSLog(@"Got something...");
  120.  
  121. NSData *d = [readHandle availableData];
  122. // go and do something with this data we wanted...
  123.  
  124. [readHandle waitForDataInBackgroundAndNotify];
  125. }
  126.  
  127. // what to do if the net service didn't publish
  128. -(void) netService:(NSNetService*) sender didNotPublish:(NSDictionary*) errorDict {
  129. NSLog(@"Net Service did not publish...");
  130. for(NSString *s in [errorDict allKeys]) {
  131. NSLog(@"Got error %@", [errorDict valueForKey:s]); // for debugging...
  132. }
  133. if([services containsObject:sender]) {
  134. [services removeObject:sender];
  135. }
  136. }
  137.  
  138.  
  139.  
  140. // what to do if the net service published correctly
  141. -(void) netServiceDidPublish:(NSNetService*) sender {
  142. NSLog(@"Hooray! We got published with name \"%@\" on port %d", [sender name], [sender port]);
  143. [services addObject:sender]; // we only want to keep track if it actually published
  144. socketHandle = [[NSFileHandle alloc] initWithFileDescriptor:[netSocket socket] closeOnDealloc:YES];
  145. if(socketHandle) {
  146. NSLog(@"should have file handle...");
  147. [socketHandle acceptConnectionInBackgroundAndNotify];
  148. }
  149. }
  150.  
  151. @end

Search