我想连接到pool.ntp.org的时间同步。所以我要创建一个套接字
sock=CFSocketCreate(NULL, PF_INET, SOCK_DGRAM, IPPROTO_UDP, kCFSocketDataCallBack|kCFSocketWriteCallBack|kCFSocketConnectCallBack, sockCallback, &sock_ctx);然后我要设置一个循环
sockref=CFSocketCreateRunLoopSource(NULL, sock, 0);
CFRunLoopAddSource(CFRunLoopGetMain(), sockref, kCFRunLoopCommonModes);并连接到地址
CFDataRef adrref=CFDataCreate(NULL, (const UInt8 *)&adr, sizeof(adr));
CFSocketError err=CFSocketConnectToAddress(sock, adrref,-1);如果我有回调kCFSocketWriteCallBack,则发送所需的数据
CFDataRef bufref=CFDataCreate(NULL, buffer, scl->NTP_PACKET_SIZE);
CFSocketError error = CFSocketSendData(scl->sock, NULL, bufref,3);直到这里开始工作为止,perfect.My的实际问题都在
else if(callbackType==kCFSocketDataCallBack)9/10次是正常的。服务器发送响应,我的进程继续进行。问题是,我在等待数据到实际,继续我的应用程序逻辑。如果没有任何数据出现,kCFSocketDataCallBack就不会被触发,并且应用程序将永远等待。有没有办法让我在等待接收数据时设置一个超时?(没有一个NSTimer来重新连接到池)
发布于 2013-10-22 00:49:52
我认为这里需要知道的是,UDP本质上是不可靠的。
因此,数据包丢失和有时得不到响应是绝对可能和正常的行为。你提到每10次中有9次有效,对于基于UDP的协议来说,这听起来相当不错。
所以我认为你真的需要让你的代码更聪明一点。我也认为使用计时器无法确定你是否在一定的时间内收到了响应。
幸运的是,在循环中调度CFRunLoopTimer非常容易。你需要做的是:
CFSocketSendData时,您还添加了一个CFRunLoopTimer。kCFSocketDataCallBack回调时,取消定时器CFRunLoopTimerSetNextFireDate重新调度它。您可以在周围保留一个计数器,每次发送数据包时都会增加计数器的数量。经过一定的尝试,你就可以放弃了。
这是一些更多的代码,但它将使您的UDP应用程序更加可靠。
https://stackoverflow.com/questions/13526058
复制相似问题