我正在尝试编写一个iOS应用程序,它侦听TCP广播并对数据执行操作。更高级的实现似乎建议使用后台线程和原始套接字来实现这种功能,但我认为作为第一次尝试,我会使用CFSocket来使事情变得简单。
问题是,当我运行它时,它很好,但它是在主线程中运行的,而不是在新线程中运行。为什么回调函数不能在后台线程中运行?
代码如下:
- (void)connecToServer{
int yes = 1;
CFSocketContext CTX = {0,self,NULL,NULL,NULL};
_socket = CFSocketCreate(kCFAllocatorDefault, PF_INET, SOCK_STREAM, IPPROTO_TCP, kCFSocketDataCallBack, TCPServerConnectCallBack, &CTX);
setsockopt(CFSocketGetNative(_socket), SOL_SOCKET, SO_REUSEADDR, (void *)&yes, sizeof(yes));
struct sockaddr_in addr4;
memset(&addr4, 0, sizeof(addr4));
addr4.sin_len = sizeof(addr4);
addr4.sin_family = AF_INET;
addr4.sin_port = htons(6242);
addr4.sin_addr.s_addr = inet_addr("");
address = CFDataCreate(kCFAllocatorDefault, (UInt8 *)&addr4, sizeof(addr4));
CFRunLoopRef cfrl = CFRunLoopGetCurrent();
CFRunLoopSourceRef source = CFSocketCreateRunLoopSource(kCFAllocatorDefault, _socket, 0);
CFRunLoopAddSource(cfrl, source, kCFRunLoopCommonModes);
CFRelease(source);
}回调函数:
static void TCPServerConnectCallBack(CFSocketRef socket, CFSocketCallBackType type, CFDataRef address, const void *data, void *info){
NSData *nsdata = (NSData*)data;
NSUInteger len = [nsdata length];
Byte *byteData = (Byte*)malloc(len);
memcpy(byteData, [nsdata bytes], len);
Byte *userData;
NetWorkConnect *netWorkConnect = (NetWorkConnect*)info;
switch(byteData[5]){
case 2:
userData = (Byte*)malloc(len-9);
memcpy(userData, byteData+7, len-9);
memset(&(netWorkConnect->oQuota), 0, sizeof(netWorkConnect->oQuota));
[netWorkConnect performSelectorOnMainThread:@selector(updateUI) withObject:nil waitUntilDone:NO];
break;
default:
break;
}
}发布于 2011-10-28 10:07:20
你可能想使用cocoaasyncsocket:它会让你的生活变得更容易。http://code.google.com/p/cocoaasyncsocket/
发布于 2021-12-04 13:04:39
kCFSocketDataCallBack设计为与run循环一起使用。后台线程,例如GCD,是运行循环的替代方案,因此不使用它们。因此,无论您处于哪个CFRunLoopGetCurrent()队列中,GCD都将始终返回主线程的运行循环。
要在后台线程上运行套接字,您需要将套接字配置为分派源。有关文件描述符的示例,请参阅Apple docs,但您只需将其与通过CFSocketGetNative()获得的套接字描述符进行交换,它就可以正常工作。
代码示例:
dispatch_queue_t _queue = dispatch_queue_create("foo", DISPATCH_QUEUE_CONCURRENT);
CFSocketRef _s_cf = CFSocketCreate(NULL, PF_INET, SOCK_DGRAM, IPPROTO_ICMP, 0, NULL, NULL);
int _s_bsd = CFSocketGetNative(_s_cf);
// make non-blocking
if (fcntl(_s_bsd, F_SETFL, O_NONBLOCK) == -1) {
// handle error
}
dispatch_source_t _readSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, _s_bsd, 0, _queue);
dispatch_source_set_event_handler(_readSource, ^{
size_t estimated = dispatch_source_get_data(self->_readSource) + 1;
NSMutableData *data = [NSMutableData dataWithCapacity:estimated];
if (read(self->_s_bsd, data.mutableBytes, estimated) == -1) {
// handle error
} else {
// handle data
}
});
dispatch_resume(_readSource);https://stackoverflow.com/questions/7721634
复制相似问题