Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Jeremy1026

macrumors 68020
Original poster
Nov 3, 2007
2,215
1,029
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.

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.
 
Then check your Console. Also, check your crash logs. Applications just don't crash quietly.

The debugger points to the line
Code:
NSLog(@"%@",incomingConnection);

Found in - (IBAction)popupChangedPicture. Which is strange, because the same line in -(void)connectionRecieved: logs perfectly without causing a crash.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.