Watsche
Watsche

Reputation: 438

socket communication at separate thread

I already read 40 pages about threading, but still not sure about my case. I have an NSObject, that open a socket connection to a device. This Object handle all the communication, sending and receiving messages and so on. I would like, that this stuff works on separate thread. I tried something like this:

- (IBAction)connect:(id)sender {
SocketConnectionController *sock = [SocketConnectionController new];
[[sock initWithParams:ip.text :port.text.intValue] performSelectorInBackground:@selector(initWithParams::) withObject:nil];
[[SocketConnectionController sharedInstance] sendCommand:GET_ID_STRING];

}

As you see, I am sending some message by using the existing instance of SocketConnectionController, but it doesn't send anything. There maybe some leak of understanding my side. I am sure, that the connection is open because of flashing lights on device. Am I creating the thread on the right way? If so, how can I use it now?

1. UPDATE: I tried something like this:

NSOperationQueue* queue = [NSOperationQueue new];
SocketConnection *sock = [SocketConnection new];
[queue addOperation:sock]; 

but at the CPU graph I see, that the stuff still running on Thread 1 (mainThread). What am I doing wrong?

2. UPDATE I found out, that the run loop, that I need for the Input and Output Stream still running on the main Thread.

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

That's why the code of 1. Update don't work. So I need to create a new Thread and then a new run loop for this thread. That can not be done automatically by Cocoa-Framework like in the code before (performSelectorInBackground).

Upvotes: 0

Views: 595

Answers (1)

Watsche
Watsche

Reputation: 438

I found the way to perform the socket connection on the separate thread:

NSThread * nThread;

- (NSThread *)networkThread {
    nThread = nil;

        nThread =
        [[NSThread alloc] initWithTarget:self
                                selector:@selector(networkThreadMain:)
                                  object:nil];
        [nThread start];

    NSLog(@"thread: %@, debug description: %@", nThread, nThread.debugDescription);
    return nThread;
}


- (void)networkThreadMain:(id)unused {
    do {
            [[NSRunLoop currentRunLoop] run];
    } while (YES);
}

- (void)scheduleInCurrentThread:(id)unused
{
    [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
                           forMode:NSRunLoopCommonModes];
    [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
                           forMode:NSRunLoopCommonModes];
}

-(BOOL) connectWithError:(NSString **) e
{
    CFReadStreamRef readStream;
    CFWriteStreamRef writeStream;
    CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"127.0.0.1", [server port], &readStream, &writeStream);
    inputStream = (__bridge NSInputStream *) readStream;
    outputStream = (__bridge NSOutputStream *) writeStream;

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

    [self performSelector:@selector(scheduleInCurrentThread:)
                 onThread:[self networkThread]
               withObject:nil
            waitUntilDone:YES];

    [inputStream open];
    [outputStream open];
}

All you need is to input this code in the new class of type NSThread.

Upvotes: 2

Related Questions