我一直在与 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 字节数组是命令)并在发送下一个命令之前等待服务器响应,为此我使用了一段时间,变量“receivedLastAnswer”是调用我的 DataCallBack 方法时设置的标志,因此如果服务器响应,则调用回调,它将标志设置为 true,因此 while 退出并发送下一个命令。
当然这不是我打算留下代码的方式,这只是为了测试并查看它是否有效,因为稍后我将不得不在 while 中添加另一个条件,一个超时条件,以防服务器没有响应一点也不。
现在,我的问题是我的应用程序,客户端,没有触发回调方法,因此它只是无限循环;我认为不触发回调的原因是因为应用程序在while循环中很忙,实际上如果我删除循环,回调就会被触发,但这对我来说没有意义,因为回调方法不是应该的在不同的线程上运行(这不是 CFRunLoopRun() 的目的吗?)并且因为它在不同的线程中运行,所以主线程处于循环中并不重要,或者我完全误解了它是如何工作的?
另外,我尝试不使用 while 循环,而是使用 Sleep() 函数,但它是相同的,没有触发回调。
你知道为什么会发生这种情况或者我该如何做到这一点,
谢谢。