NSNetServiceBrowser didRemoveService 打开流后需要更长时间

发布于 2024-12-01 03:19:39 字数 1860 浏览 0 评论 0原文

我有以下用于发现网络上的服务的代码:

[netServiceBrowser setDelegate: self]; 
[netServiceBrowser searchForServicesOfType: serviceType inDomain: domain];

这会导致调用这两个方法(查找服务和删除服务):

- (void) netServiceBrowser:(NSNetServiceBrowser*) netServiceBrowser 
         didFindService:(NSNetService*) netService ... {}

- (void) netServiceBrowser:(NSNetServiceBrowser*) netServiceBrowser 
         didRemoveService:(NSNetService*) netService ... {}

这工作正常。当我关闭设备时,我立即收到didRemoveService调用。

但是,当我打开设备的流(输入、输出或两者)时:

[netService getInputStream: &inputStream outputStream: &outputStream];

[inputStream setDelegate: self];
[outputStream setDelegate: self];

[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
             forMode: NSDefaultRunLoopMode];
[inputStream open];

[outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
              forMode:NSDefaultRunLoopMode];
[outputStream open];

NSNetServiceBrowser 突然需要近一分钟才能检测到我关闭了设备
(调用didRemoveService需要一分钟)。

我不与之通信(打开流)的设备在我删除它们后仍然会调用didRemoveService

更新: 这是与我的问题相关的更多信息。

我使用 Wireshark 进行了跟踪并注意到以下内容:

我在 iPad 模拟器中启动我的应用程序,该应用程序启动 NSNetServiceBrowser 并检测打印机。之后它会打开 设备的输入/输出流(通过机场快线、USB)。这 打印机正在向我发送状态更新,当我点击中的测试按钮时 我的应用程序打印机开始打印。在 Wireshark 中我看到了所有 按预期与打印机通信。

现在,当我在 iPad 上启动完全相同的应用程序时(并离开 iPad 模拟器正在运行)。应用程序启动 NSNetServiceBrowser 也是如此,并检测打印机。打印机是 不向我发送状态更新,当我点击测试按钮时, 打印机不打印。在 Wireshark 中我看到了通信。这 打印机或机场接收我的命令并发送 ACK 包。

一旦我关闭 iPad 模拟器应用程序,打印机就开始打印 我使用 iPad 发送的命令。似乎打开套接字会阻止所有 bonjour 事件,我该如何防止这种情况发生?

更多信息请参见:https://devforums.apple.com/message/541436

I have the following code for discovering services on the network:

[netServiceBrowser setDelegate: self]; 
[netServiceBrowser searchForServicesOfType: serviceType inDomain: domain];

That results in calls to these two methods (find service and remove service):

- (void) netServiceBrowser:(NSNetServiceBrowser*) netServiceBrowser 
         didFindService:(NSNetService*) netService ... {}

- (void) netServiceBrowser:(NSNetServiceBrowser*) netServiceBrowser 
         didRemoveService:(NSNetService*) netService ... {}

This works fine. When I turn off my device I immediately receive the didRemoveService call.

However when I open a stream (input, output or both) to the device:

[netService getInputStream: &inputStream outputStream: &outputStream];

[inputStream setDelegate: self];
[outputStream setDelegate: self];

[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
             forMode: NSDefaultRunLoopMode];
[inputStream open];

[outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
              forMode:NSDefaultRunLoopMode];
[outputStream open];

It suddenly takes the NSNetServiceBrowser almost a minute to detect that I turned off the device
(it takes a minute for didRemoveService to be called).

Devices that I'm not communicating with (opening streams with) still call didRemoveService as soon as I remove them.

Update:
Here is a bit more information related to my problem.

I've ran a trace with Wireshark and noticed the following:

I start my application in the iPad simulator, the application starts a
NSNetServiceBrowser and detects the printer. After that it opens the
input/output streams to the device (via airport express, usb). The
printer is sending me status updates and when I tap the test button in
my app the printer starts printing. In Wireshark I see all the
communication with the printer as expected.

Now when I start the exact same application on the iPad (and leave the
iPad simulator running). The application starts the
NSNetServiceBrowser as well, and detects the printer. The printer is
not sending me status updates and when I tap the test button, the
printer is not printing. In Wireshark I see the communication. The
printer or airport receives my commands and sends an ACK package.

As soon as I kill the iPad simulator app, the printer starts to print
the commands that I've sent using the iPad. It seems that opening a socket blocks all bonjour events, how can I prevent this from happening?

More here: https://devforums.apple.com/message/541436

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

无声情话 2024-12-08 03:19:39

我确信在 Lion 中,不再为 NSStreamEventEndEncountered 事件调用处理程序。因此,当您确定已收到所有数据时,您需要关闭输入流并将其从循环中删除。例如,当 NSStreamEventHasBytesAvailable 发生时。检查一下,我想它应该可以工作

I am sure its In Lion the handler is not called for the NSStreamEventEndEncountered event any more. So, you need to close your input stream and remove it from loop when you sure you have received all the data. For example when NSStreamEventHasBytesAvailable happens. Check it out and i guess it should work

你与清晨阳光 2024-12-08 03:19:39

这似乎是机场快线的限制。

我当前使用 GCDAsyncSocket 的实现工作得很好,我只需要确保只使用一个套接字与机场快线通信。

我要结束这个问题了。

It seems to be a limitation of the Airport Express.

My current implementation with GCDAsyncSocket works pretty well and I just have to make sure that only one socket is used to communicate with the Airport Express.

I'm closing the question.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文