Я работал с 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 (), но она та же, обратного вызова не было.
У вас есть идея, почему это может происходить или как я могу это сделать,
Спасибо.