简体   繁体   English

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

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

It seems to me that any NSInputStream object should pop out of its read: method if the stream is closed by another thread regardless of the other end of the socket connection. 在我看来,如果流被另一个线程关闭,而与套接字连接的另一端无关,则任何NSInputStream对象都应该从其read:方法中弹出。 But in some cases this does not appear to be true. 但是在某些情况下,这似乎并不正确。 It seems that unless the other side first sends something at least once before on the connection, the read: method will not respond to the stream closing. 似乎除非对方在连接之前至少先发送了至少一次内容,否则read:方法将不会响应流关闭。

Code to open the connection: 打开连接的代码:

    // 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];

Code to close the connection: 关闭连接的代码:

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

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

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

In the receive thread: 在接收线程中:

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

When I go to close the stream from the main thread, the receive thread remains in the read method. 当我从主线程关闭流时,接收线程保留在read方法中。 Eventually it times out and crashes. 最终它超时并崩溃。 Even the crash does not result in any kind of object being thrown (I tried to surround the code to catch anything (id) and got nothing). 甚至崩溃也不会导致抛出任何类型的对象(我试图包围代码以捕获任何内容(id)却一无所获)。

How does one reliably force read to pop out every time the streams are to be closed? 每次关闭流时,如何可靠地强制读取弹出?

Additionally: 另外:

I am using XCODE 4.4.1 on ML with 5.1 iPad simulator. 我在带有5.1 iPad模拟器的ML上使用XCODE 4.4.1。

If I only close the inputStream and do not release or set to nil, then the problem occurs as well. 如果我仅关闭inputStream而没有释放或设置为nil,那么也会发生此问题。

After much investigation I came across another thread here at SO that hinted at the answer, that since the local device is disconnecting there would not be any event from the connection (from the remote end point) that is passed through the read method. 经过大量调查,我在SO上遇到了另一个线程,该线程提示了答案:由于本地设备正在断开连接,因此不会有任何通过read方法传递的来自连接(来自远程端点)的事件。 The idea was that since the local device was responsible for disconnecting it would know that it should not enter the read method (that there would not be anything to read). 这个想法是,由于本地设备负责断开连接,因此它将知道它不应该进入读取方法(不会读取任何内容)。 This is a bit unexpected, as the user may be disconnecting when a receiver thread is already in the read method. 这有点出乎意料,因为当接收器线程已经在read方法中时,用户可能会断开连接。 BUT... iOS was designed apparently not to rely upon receiver threads, but events in the run loop (which is another issue, but I don't want to get into that here). 但是... iOS的设计显然不依赖于接收器线程,而是依赖于运行循环中的事件(这是另一个问题,但我不想在这里讨论)。 Specifically, given an event from the run loop that says there is data available, you enter the read method. 具体来说,给定运行循环中的事件说有可用数据,则您可以输入read方法。 Thus you never enter read and hang waiting for the first byte. 因此,您永远不会输入read并挂起等待第一个字节。 This is very different than socket programming that I have done on a windows platform in the past. 这与我过去在Windows平台上完成的套接字编程完全不同。 But all the experimenting I have done thus far indicates this is the problem. 但是到目前为止,我所做的所有实验都表明这是问题所在。 I have a solution that works now that relies upon events from the stream that come out of a run loop in a worker thread so that network traffic does not interfere with the GUI(main) thread. 我有一个现在可以运行的解决方案,该解决方案依赖于工作线程中来自运行循环的流中的事件,因此网络流量不会干扰GUI(main)线程。

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

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