首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >iphone网络cfsocket回调多线程

iphone网络cfsocket回调多线程
EN

Stack Overflow用户
提问于 2011-10-11 13:11:14
回答 2查看 1.5K关注 0票数 2

我正在尝试编写一个iOS应用程序,它侦听TCP广播并对数据执行操作。更高级的实现似乎建议使用后台线程和原始套接字来实现这种功能,但我认为作为第一次尝试,我会使用CFSocket来使事情变得简单。

问题是,当我运行它时,它很好,但它是在主线程中运行的,而不是在新线程中运行。为什么回调函数不能在后台线程中运行?

代码如下:

代码语言:javascript
复制
- (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);
}

回调函数:

代码语言:javascript
复制
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;
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-10-28 10:07:20

你可能想使用cocoaasyncsocket:它会让你的生活变得更容易。http://code.google.com/p/cocoaasyncsocket/

票数 0
EN

Stack Overflow用户

发布于 2021-12-04 13:04:39

kCFSocketDataCallBack设计为与run循环一起使用。后台线程,例如GCD,是运行循环的替代方案,因此不使用它们。因此,无论您处于哪个CFRunLoopGetCurrent()队列中,GCD都将始终返回主线程的运行循环。

要在后台线程上运行套接字,您需要将套接字配置为分派源。有关文件描述符的示例,请参阅Apple docs,但您只需将其与通过CFSocketGetNative()获得的套接字描述符进行交换,它就可以正常工作。

代码示例:

代码语言:javascript
复制
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);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7721634

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档