- CocoaAsyncSocket provides easy-to-use and powerful asynchronous socket libraries for Mac and iOS. The classes are described below.
- The CocoaAsyncSocket library comes into play when we have to deal with sockets, ports, and connections. It also helps us with sending data from one end of the connection to the other end, in both directions. Even though Bonjour is not responsible for establishing a connection between two processes, it does provide us with information that we need to establish the connection. As I mentioned earlier in this series, Bonjour and the CocoaAsyncSocket are a powerful combination as you will see in this article.
GCDAsyncSocket *asyncSocket; NSString *strIPAddress; NSString *strPortNumber - (void)startServer { if(asyncSocket) { [asyncSocket disconnect]; } else { asyncSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()]; } strIPAddress = @""; strIPAddress = [self getIPAddress]; strPortNumber = @""; // Create our socket. // We tell it to invoke our delegate methods on the main thread. // Create an array to hold accepted incoming connections. connectedSockets = [[NSMutableArray alloc] init]; // Now we tell the socket to accept incoming connections. // We don't care what port it listens on, so we pass zero for the port number. // This allows the operating system to automatically assign us an available port. NSError *err = nil; if ([asyncSocket acceptOnPort:8080 error:&err]) { // So what port did the OS give us? UInt16 port = [asyncSocket localPort]; // UInt16 port = 7070; _strPortNumber = [NSString stringWithFormat:@"%d",port]; netService = [[NSNetService alloc] initWithDomain:@"local." type:@"_CinchGamingService._tcp." name:@"" port:port]; [netService setDelegate:self]; [netService publish]; NSMutableDictionary *txtDict = [NSMutableDictionary dictionaryWithCapacity:2]; [txtDict setObject:@"CinchGaming" forKey:@"GameName"]; [txtDict setObject:@"InheritX" forKey:@"Company"]; NSData *txtData = [NSNetService dataFromTXTRecordDictionary:txtDict]; [netService setTXTRecordData:txtData]; } else { NSLog(@"Error in acceptOnPort:error: -> %@", err); [self startServer]; } //if ([_delegate respondsToSelector:@selector(socketConnectedToIP:andPort:)]) // [_delegate socketConnectedToIP:_strIPAddress andPort:_strPortNumber]; } - (void)sendMessage:(NSString*)pstrMessage { for (GCDAsyncSocket *objTmpSocket in connectedSockets) { NSString *welcomeMsg = pstrMessage; NSData *welcomeData = [welcomeMsg dataUsingEncoding:NSUTF8StringEncoding]; [objTmpSocket writeData:welcomeData withTimeout:-1 tag:1]; } } - (NSString *)getIPAddress { NSString *address = @"error"; struct ifaddrs *interfaces = NULL; struct ifaddrs *temp_addr = NULL; int success = 0; // retrieve the current interfaces - returns 0 on success success = getifaddrs(&interfaces); if (success == 0) { // Loop through linked list of interfaces temp_addr = interfaces; while (temp_addr != NULL) { if( temp_addr->ifa_addr->sa_family == AF_INET) { // Check if interface is en0 which is the wifi connection on the iPhone if ([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"]) { // Get NSString from C String address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)]; } } temp_addr = temp_addr->ifa_next; } } // Free memory freeifaddrs(interfaces); return address; } -(void)stopServer { [asyncSocket disconnect]; } #pragma mark - Cocoa Async Delegates - (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag { if ([_delegate respondsToSelector:@selector(socketWrote:)]) [_delegate socketWrote:YES]; } - (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket { [KSToastView ks_showToast:@"Your application has been successfully connected to cinch app." duration:5.0f]; NSLog(@"Accepted new socket from %@:%hu", [newSocket connectedHost], [newSocket connectedPort]); [connectedSockets addObject:newSocket]; } - (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err { [connectedSockets removeObject:sock]; } #pragma mark - Netservice Delegate - (void)netServiceDidPublish:(NSNetService *)ns { [UIApplication sharedApplication].idleTimerDisabled = YES; NSLog(@"IP Address :- %@ Port :- %i",_strIPAddress,(int)[ns port]); } - (void)netService:(NSNetService *)ns didNotPublish:(NSDictionary *)errorDict { NSLog(@"Failed to Publish Service: domain(%@) type(%@) name(%@) - %@",[ns domain], [ns type], [ns name], errorDict); [self startServer]; } @end