I am trying to send data between devices using bonjour. I have successfully created a NSNetService and opened a socket up to talk through. When I attempt to send data though, I get a crash. Here is my code.
When it crashes I don't get any information in my console as to the cause of the crash, the application just quits quietly. I have been fighting this thing for about 2 straight days, and help diagnosing and fixing it would be hugely appreciated.
Code:
.h
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
@interface ViewController : UIViewController {
NSNetService * netService;
NSFileHandle * listeningSocket;
NSFileHandle * incomingConnection;
}
@property (nonatomic,retain) NSFileHandle * incomingConnection;
- (IBAction)popupChangedPicture;
@end
Code:
.m
#import "NumberPadViewController.h"
//required to network connection
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
@implementation ViewController
@synthesize incomingConnection;
- (void)viewDidLoad {
[super viewDidLoad];
incomingConnection = [[NSFileHandle alloc] init];
netService.delegate = self;
uint16_t chosenPort = 0;
UIDevice *myDevice = [UIDevice currentDevice];
serviceNameField = [myDevice name];
// serviceNameField = [NSString stringWithFormat:@"riiPhone"];
if(!listeningSocket) {
// Here, create the socket from traditional BSD socket calls, and then set up an NSFileHandle with that to listen for incoming connections.
int fdForListening;
struct sockaddr_in serverAddress;
socklen_t namelen = sizeof(serverAddress);
// In order to use NSFileHandle's acceptConnectionInBackgroundAndNotify method, we need to create a file descriptor that is
// itself a socket, bind that socket, and then set it up for listening. At this point, it's ready to be handed off to
// acceptConnectionInBackgroundAndNotify.
if((fdForListening = socket(AF_INET, SOCK_STREAM, 0)) > 0) {
memset(&serverAddress, 0, sizeof(serverAddress));
serverAddress.sin_family = AF_INET;
serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);
serverAddress.sin_port = 0; // allows the kernel to choose the port for us.
if(bind(fdForListening, (struct sockaddr *)&serverAddress, sizeof(serverAddress)) < 0) {
close(fdForListening);
return;
}
// Find out what port number was chosen for us.
if(getsockname(fdForListening, (struct sockaddr *)&serverAddress, &namelen) < 0) {
close(fdForListening);
return;
}
chosenPort = ntohs(serverAddress.sin_port);
if(listen(fdForListening, 1) == 0) {
listeningSocket = [[NSFileHandle alloc] initWithFileDescriptor:fdForListening closeOnDealloc:YES];
}
}
}
if(!netService) {
// lazily instantiate the NSNetService object that will advertise on our behalf.
netService = [[NSNetService alloc] initWithDomain:@"" type:@"_wwdcpic._tcp." name:serviceNameField port:chosenPort];
[netService setDelegate:self];
}
if(netService && listeningSocket) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(connectionReceived:) name:NSFileHandleConnectionAcceptedNotification object:listeningSocket];
[listeningSocket acceptConnectionInBackgroundAndNotify];
[netService publish];
}
}
//this is called when i choose this device from the 2nd device
- (void)connectionReceived:(NSNotification *)aNotification {
//this sets incomingConnection to the proper location of where the data is coming from
incomingConnection = [[aNotification userInfo] objectForKey:NSFileHandleNotificationFileHandleItem];
//they match, good
NSLog(@"%@",[[aNotification userInfo] objectForKey:NSFileHandleNotificationFileHandleItem]);
NSLog(@"%@",incomingConnection);
//connected, good
NSLog(@"Connected");
}
- (IBAction)popupChangedPicture {
NSString *aStr = @"4";
NSData * representationToSend = [aStr dataUsingEncoding: NSASCIIStringEncoding];
NSLog(@"Log1");
NSLog(@"%@",incomingConnection);
NSLog(@"Log2");
//right here it crashes, it seems like incomingConnection isn't being properly set or something
[incomingConnection writeData:representationToSend];
NSLog(@"Log3");
[incomingConnection closeFile];
NSLog(@"Log4");
}
- (void)netService:(NSNetService *)sender didNotPublish:(NSDictionary *)errorDict {
NSLog(@"Did Not Publish");
[listeningSocket release];
listeningSocket = nil;
[netService release];
netService = nil;
}
- (void)netServiceDidStop:(NSNetService *)sender {
NSLog(@"Service Stopped");
[netService release];
netService = nil;
}
- (void)netServiceWillPublish:(NSNetService *)sender {
NSLog(@"Will Publish");
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[super dealloc];
}
@end
When it crashes I don't get any information in my console as to the cause of the crash, the application just quits quietly. I have been fighting this thing for about 2 straight days, and help diagnosing and fixing it would be hugely appreciated.