OS X: как смотреть события чтения сокетов с помощью NSRunLoop?

Я пишу приложение Какао. В приложении есть сокет, и всякий раз, когда сокет становится читаемым, я хочу прочитать данные из сокета, обработать данные и соответствующим образом обновить пользовательский интерфейс. Я хочу интегрировать проверку события чтения в основной цикл, то есть я хочу присоединить сокет к основному циклу и сделать так, чтобы основной цикл вызывал обратный вызов всякий раз, когда этот сокет становится читаемым.

Я написал тестовое приложение, но по какой-то причине оно не работает:

#include <stdio.h>
#include <Foundation/NSAutoReleasePool.h>
#include <Foundation/NSRunLoop.h>
#include <Foundation/NSPort.h>

@interface MyDelegate : NSObject <NSPortDelegate> {
}
- (void)handlePortMessage:(NSPortMessage *)portMessage;
@end

@implementation MyDelegate
- (void)handlePortMessage:(NSPortMessage *)portMessage {
    printf("Haiz\n");
}
@end

int
main() {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    NSSocketPort *server = [NSSocketPort alloc];
    MyDelegate *foo = [MyDelegate alloc];
    [server initWithTCPPort: 1234];
    [server setDelegate: foo];
    [[NSRunLoop mainRunLoop] addPort: server forMode: NSDefaultRunLoopMode];
    [[NSRunLoop mainRunLoop] run];
    [pool release];
    return 0;
}

Предполагается, что приложение прослушивает локальный порт 1234, и всякий раз, когда кто-либо подключается к серверу или отправляет данные на сервер, приложение должно выводить "Haiz" на консоли. Однако приложение ничего не делает. Сокет создан, и я могу подключиться к порту 1234, но приложение ничего не выводит на консоль.

Что я делаю неправильно?

2 ответа

Решение

Из документации:

Объект NSSocketPort может использоваться в качестве конечной точки для соединений распределенных объектов.

Это не то, что вы делаете здесь.

Ты хочешь или NSFileHandle вокруг дескриптора файла сокета из API сокетов BSD, или CFSocket. Это позволит вам поместить сокет в цикл выполнения.

Вы хотите использовать NSSocketPort так, как вы делаете, но затем создайте NSFileHandle принимать соединения на сокете. Вы можете получить обратные вызовы в главном потоке, как вы ожидаете, сначала для новых соединений, а затем для данных об этих соединениях. Используйте эту статью О'Рейли и просто игнорируйте HTTP.

Другие вопросы по тегам