简体   繁体   English

NSNetService发布,但didAcceptConnectionWithInputStream…从未被调用

[英]NSNetService publishes, but didAcceptConnectionWithInputStream… is never called

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 ). 我一直在尝试在iOS上制作一个简单的应用程序,该应用程序将收到一条消息,然后根据该消息执行操作(此刻,我只想通过NSLog进行显示)。 I can connect to the service, but the service never seems to receive anything. 我可以连接到该服务,但是该服务似乎从未收到任何东西。 Here's my .h file: 这是我的.h文件:

#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: 和我的.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 (ie my own implementation receives the NSStreamEventHasSpaceAvailable and NSStreamEventOpenCompleted events via stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode ). 当我使用Bonjour Browser时 ,可以看到该服务,并且当我使用自己的NSNetServiceBrowser实现或Bill NSNetServiceBrowser的示例( 博客文章代码 )时,它似乎已建立连接(即,我自己的实现收到NSStreamEventHasSpaceAvailableNSStreamEventOpenCompleted通过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. 我还是iOS的新手,所以我希望这只是一些愚蠢的错误,可以很容易地解决。

-[NSNetService publish] simply publishes the service; -[NSNetService publish]仅发布服务; you're responsible for creating a socket and listening on the port you give to the NSNetService initializer. 您负责创建套接字并侦听提供给NSNetService初始化程序的端口。 You won't receive netService:didAcceptConnectionWithInputStream:outputStream: because the NSNetService knows nothing about the socket. 您不会收到netService:didAcceptConnectionWithInputStream:outputStream:因为NSNetService对套接字一无所知。

If you want the NSNetService to manage the socket for you—and send didAcceptConnection... —use -[NSNetService publishWithOptions:] : 如果您希望NSNetService为您管理套接字并发送didAcceptConnection...使用-[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. 在这种情况下,您需要确保用于初始化NSNetService的端口未使用。 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. 您的getPort方法永远不会关闭套接字(并且会泄漏CFSocketRef),因此在发布服务时将使用该套接字,从而导致错误。

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." 我建议您删除getPort并按照Apple在NSNetServices.h中的建议,“将端口号指定为零以使用随机端口。”

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM