Почему метод прослушивания DataCallBack в фоновом режиме не вызывается?
Я работал с 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-байтовый массив, который вы видите, это команда) и подождать, пока сервер ответит, прежде чем отправлять следующую команду. Для этого я использую некоторое время, переменная "receiveLastAnswer" флаг, который устанавливается, когда вызывается мой метод DataCallBack, поэтому, если сервер отвечает, вызывается обратный вызов, он устанавливает для флага значение true, и, таким образом, while завершается и отправляется следующая команда.
Конечно, это не то, как я собираюсь оставить код, это просто для тестирования и проверки, работает ли он, потому что позже мне придется добавить другое условие в то время, как условие тайм-аута, если сервер не отвечает совсем.
Теперь моя проблема в том, что мое приложение, клиент, не запускает метод обратного вызова, и поэтому оно просто бесконечно циклически повторяется; Я думаю, что причина для того, чтобы не запускать обратный вызов, состоит в том, что приложение занято в цикле while, фактически, если я удаляю цикл, вызывается обратный вызов, но это не имеет смысла для меня, потому что метод обратного вызова не предполагается работать в другом потоке (разве это не цель CFRunLoopRun()?), и поскольку он выполняется в другом потоке, не должно иметь значения, что основной поток находится в цикле, или я совершенно не понимаю, как это работает?
Кроме того, я попытался использовать не цикл while, а функцию Sleep(), но это то же самое, обратный вызов не запускается.
У вас есть идея, почему это может происходить или как я могу это сделать,
Благодарю.
1 ответ
Что ж, я думаю, что на самом деле мои данные Callback не будут вызываться, если основной поток занят или заблокирован, поэтому я оставил метод Callback в главном потоке и поместил мой метод send в другой поток, на самом деле он работал довольно хорошо, Тем не менее, я все еще брожу, есть ли другой путь, но сейчас он делает то, что мне нужно, поэтому я буду придерживаться его.