为什么DataCallBack方法在后台侦听未被调用?
我一直在与CFNetwork合作为iPad创建一个客户端应用程序,它是一个小应用程序,没有任何幻想。为什么DataCallBack方法在后台侦听未被调用?
这是我如何创建连接到服务器(在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个字节数组,你看到的是命令),然后等待服务器在发送下一个命令之前做出响应,为此,我使用了一段时间,变量“receivedLastAnswer”是一个标志,当我的DataCallBack方法被调用时被设置,所以如果服务器响应,回调被调用,它将该标志设置为真因此该时间退出并且下一个命令被发送。
当然,这不是我打算如何离开代码,这只是为了测试,看看它是否有效,以后我将不得不另外添加一个条件到一个超时条件,以防服务器根本没有回应。
现在,我的问题是,我的应用程序,客户端,没有触发回调方法,因此它只是无限循环;我认为不发起回调的原因是因为应用程序在while循环中忙碌,事实上,如果我删除循环,回调被触发,但这对我没有意义,因为不是回调方法在不同的线程上运行(不是CFRunLoopRun()的目的?),并且因为它运行在不同的线程中,所以主线程应该在一个循环中或者我完全误解了它的工作方式?另外,我尝试不使用while循环,但使用Sleep()函数,但它是一样的,没有回调被触发。
你有任何想法,为什么这可能发生或我怎么能做到这一点,
感谢。
嗯,我认为在行动我的数据回调不会被称为如果主线程忙或阻塞,所以我做的是离开回调方法的主线程,并把我的发送方法在另一个线程,它的工作实际上相当不错,但是如果还有其他方法,我仍然在游荡,但现在它满足了我的需求,所以我会坚持下去。