NSNetService publishes, but didAcceptConnectionWithInputStream… is never called

梦想与她 提交于 2020-01-06 15:15:51

问题


I've been trying to make a simple app on iOS that will receive a message, and then perform an action based on that message (at the moment I just want to show it via NSLog). I can connect to the service, but the service never seems to receive anything. Here's my .h file:

#import <Foundation/Foundation.h>
#import <arpa/inet.h>

@interface PalServiceController : NSObject <NSNetServiceDelegate>

@property (nonatomic, strong) NSNetService *ns;
@property (nonatomic, strong) NSOutputStream *ostream;

- (void)start;
+ (int)getPort;
- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode;

@end

and my .m:

#import "PalServiceController.h"

@implementation PalServiceController

- (void)start
{
    // Start a net service
    int port = [PalServiceController getPort];
    NSLog(@"Opening on port %i", port);
    self.ns = [[NSNetService alloc] initWithDomain:@""
                                              type:@"_TestingProtocol._tcp."
                                              name:@"Test Name For iPhone"
                                              port:port];
    if (self.ns) {
        [self.ns setDelegate:self];
        [self.ns publish];
        self.ns.delegate = self;
    } else {
        NSLog(@"Error starting service");
    }

}

/*
 * Code from: http://stackoverflow.com/a/11723158/657676
 */
+ (int) getPort
{
 ...   
}

- (void)netServiceWillResolve:(NSNetService *)sender
{
    NSLog(@"Resolving");
}

- (void)netServiceDidResolveAddress:(NSNetService *)sender
{
    NSLog(@"Resolved Address");
}

- (void)netService:(NSNetService *)sender didNotPublish:(NSDictionary *)errorDict
{
    NSLog(@"Error publishing");
}

- (void)netService:(NSNetService *)sender didAcceptConnectionWithInputStream:(NSInputStream *)inputStream outputStream:(NSOutputStream *)outputStream
{
    NSLog(@"Got a connection! (server)");
    // Close self down
    [self.ns stopMonitoring];
    [self.ns stop];
}

- (void)netService:(NSNetService *)sender didNotResolve:(NSDictionary *)errorDict
{
    NSLog(@"Error resolving");
}
- (void)netServiceDidPublish:(NSNetService *)sender
{
    NSLog(@"Published server");
}

- (void)netServiceDidStop:(NSNetService *)sender
{
    NSLog(@"Server stopped");
}

- (void)netService:(NSNetService *)sender didUpdateTXTRecordData:(NSData *)data
{
    NSLog(@"Updated TXT Record");
}

- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode
{
    NSLog(@"Event on server");
    switch(eventCode) {
        ...
    }
}

@end

This is called via:

self.controller = [[PalServiceController alloc] init];
[self.controller start];

When I use Bonjour Browser, I can see the service, and when I use either my own implementation of an NSNetServiceBrowser or the example from Bill Dudney(blog post, code), it seems to connect (i.e. my own implementation receives the NSStreamEventHasSpaceAvailable and NSStreamEventOpenCompletedevents via stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode). However, none of the methods above get called on the server.

I'm still new to iOS, so I'm hoping that this is just some silly mistake that can be easily fixed.


回答1:


-[NSNetService publish] simply publishes the service; you're responsible for creating a socket and listening on the port you give to the NSNetService initializer. You won't receive netService:didAcceptConnectionWithInputStream:outputStream: because the NSNetService knows nothing about the socket.

If you want the NSNetService to manage the socket for you—and send didAcceptConnection...—use -[NSNetService publishWithOptions:]:

[self.ns publishWithOptions:NSNetServiceListenForConnections];

In this case, you need to make sure that the port with which you initialize the NSNetService is unused. Your getPort method never closes the socket (and leaks the CFSocketRef), so it will be in use when you publish the service, leading to an error.

I'd recommend that you remove getPort and, as Apple suggests in NSNetServices.h, "[s]pecify a port number of zero to use a random port."



来源:https://stackoverflow.com/questions/21503970/nsnetservice-publishes-but-didacceptconnectionwithinputstream-is-never-calle

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!