繁体   English   中英

如果[nsInputStream close]被另一个线程调用,是否应该返回[nsInputStream read:…]?

[英]Should [nsInputStream read:…] return if [nsInputStream close] is called by another thread?

在我看来,如果流被另一个线程关闭,而与套接字连接的另一端无关,则任何NSInputStream对象都应该从其read:方法中弹出。 但是在某些情况下,这似乎并不正确。 似乎除非对方在连接之前至少先发送了至少一次内容,否则read:方法将不会响应流关闭。

打开连接的代码:

    // Open the socket...
    CFStreamCreatePairWithSocketToHost(NULL, Host, Port, &readStream, &writeStream);

    // Create NSStream objects for our use...
    inputStream = (NSInputStream *)readStream;
    outputStream = (NSOutputStream *)writeStream;

    // take ownership of the NSStream objects...
    [inputStream retain];
    [outputStream retain];

    // open the streams....
    [inputStream open];
    [outputStream open];

关闭连接的代码:

    // Close the streams...
    [inputStream close];
    [outputStream close];

    // Release ownership...
    [outputStream release];
    [inputStream release];

    // clear reference values...
    outputStream = nil;
    inputStream = nil;

在接收线程中:

-(uint8_t) GetByte
{
    uint8_t c;
    int N = [inputStream read:&c maxLength:1];
    if ( N < 1 )
        @throw [[TcpClientException alloc] init];
    return c;
}

当我从主线程关闭流时,接收线程保留在read方法中。 最终它超时并崩溃。 甚至崩溃也不会导致抛出任何类型的对象(我试图包围代码以捕获任何内容(id)却一无所获)。

每次关闭流时,如何可靠地强制读取弹出?

另外:

我在带有5.1 iPad模拟器的ML上使用XCODE 4.4.1。

如果我仅关闭inputStream而没有释放或设置为nil,那么也会发生此问题。

经过大量调查,我在SO上遇到了另一个线程,该线程提示了答案:由于本地设备正在断开连接,因此不会有任何通过read方法传递的来自连接(来自远程端点)的事件。 这个想法是,由于本地设备负责断开连接,因此它将知道它不应该进入读取方法(不会读取任何内容)。 这有点出乎意料,因为当接收器线程已经在read方法中时,用户可能会断开连接。 但是... iOS的设计显然不依赖于接收器线程,而是依赖于运行循环中的事件(这是另一个问题,但我不想在这里讨论)。 具体来说,给定运行循环中的事件说有可用数据,则您可以输入read方法。 因此,您永远不会输入read并挂起等待第一个字节。 这与我过去在Windows平台上完成的套接字编程完全不同。 但是到目前为止,我所做的所有实验都表明这是问题所在。 我有一个现在可以运行的解决方案,该解决方案依赖于工作线程中来自运行循环的流中的事件,因此网络流量不会干扰GUI(main)线程。

暂无
暂无

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

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