已经提出了类似的问题,但问题似乎是特定于代码的,所以希望这是可以的。
我正在尝试编写一个监听UDP广播并对数据进行操作的iOS应用程序。更高级的实现似乎建议使用后台线程和原始套接字来实现这种功能,但我认为作为第一次尝试,我将使用CFSocket来保持简单。我研究过Apple的UDPEcho示例,但已经碰壁了。
我将CFSocket添加到RunLoop,但我的回调永远不会被调用。与此类代码一样,这很难调试。我已经在UDPEcho中使用了很多错误检查,一切似乎都得到了正确的设置。这是代码:
我有一个名为DataListener的对象来管理连接。这是在DataListener init中(删除了错误检查:
int sock;
int err;
CFRunLoopSourceRef rls;
const CFSocketContext context = { 0, self, NULL, NULL, NULL };
sock = socket(AF_INET, SOCK_DGRAM, 0);
# Setup address struct and bind to socket for broadcast
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_len = sizeof(addr);
addr.sin_family = AF_INET;
addr.sin_port = 51234;
addr.sin_addr.s_addr = INADDR_ANY;
err = bind(sock, (const struct sockaddr *) &addr, sizeof(addr));
# Set flags to non-blocking
int flags;
flags = fcntl(sock,F_GETFL);
err = fcntl(sock, F_SETFL, flags | O_NONBLOCK);
# CFSocket is created, stored in the object
self->_cfSocket = CFSocketCreateWithNative(NULL,sock,kCFSocketReadCallBack,
SocketReadCallback, &context);
sock = -1;
# CFSocket is added to the Main RunLoop
rls = CFSocketCreateRunLoopSource(NULL,self->_cfSocket,0);
CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
CFRelease(rls);
此函数用于获取C回调(此函数未按预期调用):
static void SocketReadCallback(CFSocketRef s, CFSocketCallBackType type, CFDataRef address, const void *data, void *info){
DataListener* obj;
obj = (DataListener*) info;
NSLog(@"Got callback in C");
[obj readData];
}
DataListener readData函数是一个Obj-C函数,然后处理数据。
我的设置代码有问题吗?有没有办法验证CFSocket是否正确地放在RunLoop上?
感谢您阅读材料的任何提示或建议。我意识到将来我应该使用一个线程,但是对于这个例子,我想弄清楚如何用CFSocket做这个。
更新:从未弄清楚这里出了什么问题。转移到asyncsocket:http://code.google.com/p/cocoaasyncsocket/,生活很美好。
答案 0 :(得分:1)
kCFSocketReadCallBack更改为kCFSocketDataCallBack
答案 1 :(得分:1)
尝试将CFRunLoopGetCurrent()替换为CFRunLoopGetMain()