Почему прослушивание метода DataCallBack в фоновом режиме не вызывается? - PullRequest
0 голосов
/ 18 июня 2010

Я работал с CFNetwork над созданием клиентского приложения для iPad, это маленькое приложение, ничего особенного.

Так я создаю соединение с сервером (работает в windows).

- (void) startConnection
{
    char ip[] = "192.168.0.244";
    NSString *ipAddress = [[NSString alloc] initWithCString:ip];

    /* Build our socket context; this ties an instance of self to the socket */
    CFSocketContext CTX = { 0, self, NULL, NULL, NULL };

    /* Create the server socket as a TCP IPv4 socket and set a callback */
    /* for calls to the socket's lower-level connect() function */  
    TCPClient = CFSocketCreate(NULL, PF_INET, SOCK_STREAM, IPPROTO_TCP,
                               kCFSocketDataCallBack, (CFSocketCallBack)DataCallBack, &CTX);

    if (TCPClient == NULL)
        return;

    /* Set the port and address we want to listen on */
    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    addr.sin_len = sizeof(addr);
    addr.sin_family = AF_INET;
    addr.sin_port = htons(PORT);// PORT = 5001
    addr.sin_addr.s_addr = inet_addr([ipAddress UTF8String]);

    CFDataRef connectAddr = CFDataCreate(NULL, (unsigned char *)&addr, sizeof(addr));
    CFSocketConnectToAddress(TCPClient, connectAddr, -1);
    CFRunLoopSourceRef sourceRef =
    CFSocketCreateRunLoopSource(kCFAllocatorDefault, TCPClient, 0);
    CFRunLoopAddSource(CFRunLoopGetCurrent(), sourceRef, kCFRunLoopCommonModes);
    CFRelease(sourceRef);
    CFRunLoopRun();
} 

Как видите, когда я создаю сокет сервера, я регистрирую обратный вызов для прослушивания входящих данных с сервера.

Затем я использую методы CFRunLoopAddSource (...) и CFRunLoopRun () для прослушивания этого обратного вызова в фоновом режиме.

Вот так выглядит мой метод отправки

- (void) send
{
    if (TCPClient == NULL)
        return;

    Byte byteData[3];   
    for (int i = 1; i <= 25; i++) {
        receivedLastAnswer = NO;
        globalPos = i;
        byteData[0] = i;
        byteData[1] = 4;
        byteData[2] = 0;
        int len = 3;//strlen(byte)+1;               
        CFDataRef refData = CFDataCreate(kCFAllocatorDefault, byteData, len);
        CFSocketSendData(TCPClient, NULL, refData, 0);
        while (!receivedLastAnswer) {
            //this while is to wait until a response is send by the server
         }
    }
}

Что я хочу сделать, это отправить команду на сервер (3-байтовый массив, который вы видите, это команда) и дождаться ответа сервера, прежде чем отправлять следующую команду, для этого я использую переменную while, while " receiveLastAnswer "- это флаг, который устанавливается, когда вызывается мой метод DataCallBack, поэтому, если сервер отвечает, вызывается обратный вызов, он устанавливает для флага значение true, и, таким образом, время выхода и отправка следующей команды.

Конечно, я не собираюсь покидать код, это просто для тестирования и проверки работоспособности, потому что позже мне придется добавить другое условие while, условие тайм-аута, если сервер не вообще не отвечаю.

Теперь моя проблема в том, что мое приложение, клиент, не запускает метод обратного вызова, и поэтому оно просто бесконечно циклически повторяется; Я думаю, что причина для того, чтобы не запускать обратный вызов, состоит в том, что приложение занято в цикле while, фактически, если я удаляю цикл, вызывается обратный вызов, но это не имеет смысла для меня, потому что не предполагается метод обратного вызова работать в другом потоке (разве это не цель CFRunLoopRun ()?) и поскольку он выполняется в другом потоке, не должно иметь значения, что основной поток находится в цикле, или я совершенно не понимаю, как это работает

Кроме того, я попытался не использовать цикл while, а функцию Sleep (), но она та же, обратного вызова не было.

У вас есть идея, почему это может происходить или как я могу это сделать,

Спасибо.

1 Ответ

0 голосов
/ 19 июня 2010

Ну, я думаю, что на самом деле мои данные Callback не будут вызываться, если основной поток занят или заблокирован, поэтому я оставил метод Callback в главном потоке и поместил свой метод send в другой поток, он работал довольнону, на самом деле, однако я все еще брожу, если будет другой путь, но сейчас он делает то, что мне нужно, поэтому я буду придерживаться этого.

...