【问题标题】:NSStream write to socket gives no error with WiFi turned off. Why?NSStream 写入套接字不会在 WiFi 关闭时出现错误。为什么?
【发布时间】:2014-01-21 18:25:39
【问题描述】:

美好的一天,

我正在 iPhone 上为 PC 上运行的应用程序编写自定义控制器。我正在使用标准编码在我的 ios 客户端上设置和打开套接字并写入/接收数据。一切都很好,直到我去了一个 wifi 连接较弱的区域,iPhone 或 PC 失去了连接。我使用Reachability 在 iPhone 上添加了一个 wifi 连接测试,它按预期工作。我假设使用与NSStream 相关的三种可能的错误检查方法之一会让我知道连接的远程端(即 PC)是否有问题。

我首先发送了一条[outputStream streamStatus] 消息,希望在我关闭 PC 上的 wifi 适配器时获得一个 NSStreamStatusError 代码。我得到的是一个NSStreamStatusOpen 代码。

第二次尝试是检查来自 write: maxLength: 的 -1 返回码。相反,这给出了成功发送的字节数(假设)。

第三次尝试是明确地查看NSStream 代表正在接收什么代码。大多数时候是NSStreamEventHasSpaceAvailable,但从不是NSStreamEventErrorOccurred

有人知道为什么吗? NSStreamReachability(旧版)类似吗?只要手机有连接就开心吗?

感谢您提供任何见解。

RB

【问题讨论】:

    标签: ios iphone sockets nsstream


    【解决方案1】:

    有时,尤其是使用套接字时,流可能会遇到错误,从而阻止进一步处理流数据。通常,错误表示流的一端缺少某些东西,例如远程主机崩溃或正在流式传输的文件的删除。当大多数错误发生时,流的客户端可以做一些事情,除了向用户报告错误。报错的流对象虽然可以在关闭前查询状态,但不能重复用于读写操作。

    NSStreamNSOutputStream 类会通过多种方式通知您是否发生错误:

    1.如果流对象被安排在一个运行循环上,该对象会在stream:handleEvent: message 中向其委托报告NSStreamEventErrorOccurred 事件。

    2.客户端可以随时向流对象发送streamStatus消息,看是否返回NSStreamStatusError

    3.如果您尝试通过发送write:maxLength: 来写入NSOutputStream 对象并且它返回-1,则发生了写入错误。

    一旦您确定流对象遇到错误,您可以使用 streamError 消息查询该对象以获取有关错误的更多信息(以 NSError 对象的形式)。接下来,通知用户该错误。清单 1 显示了运行循环调度的流对象的委托如何处理错误。

    - (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode {
        NSLog(@"stream:handleEvent: is invoked...");
    
        switch(eventCode) {
            case NSStreamEventErrorOccurred:
            {
                NSError *theError = [stream streamError];
                NSAlert *theAlert = [[NSAlert alloc] init];
                [theAlert setMessageText:@"Error reading stream!"];
                [theAlert setInformativeText:[NSString stringWithFormat:@"Error %i: %@",
                    [theError code], [theError localizedDescription]]];
                [theAlert addButtonWithTitle:@"OK"];
                [theAlert beginSheetModalForWindow:[NSApp mainWindow]
                    modalDelegate:self
                    didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:)
                    contextInfo:nil];
                [stream close];
                [stream release];
                break;
            }
            // continued ....
        }
    }
    

    更多详情:Developer.Apple - Handling Stream Errors

    【讨论】:

    • 拉姆沙德:谢谢。用于上传/链接到文档。正如您从问题中看到的那样,我尝试了所有三种建议的方法,但是尽管我通过关闭其 wifi 连接来模拟“远程主机的崩溃”,但它们都没有给我错误。仍然没有更聪明。 RB
    猜你喜欢
    • 2018-05-20
    • 2021-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多