iOS and OS X Network Programming Cookbook |Creating an echo server(CFSocket)
2015-06-30 23:46
573 查看
建立socket的方法与BSD socket相同(见上一篇),主要的不同在监听上,这里使用的是run loop对socket进行监听,这是CFNetwork的一个很大的优势
在通过BSD socket获取到listening descriptor后,通过CFSocketCreateWithNative()创建CFSocket,(这个步骤的逆向是CFSocketGetNative())然后将其加入run loop中
其实大家都知道BSD基本没有实用性,CFSocket还能用用
CFAllocatorRef:用来定位新对象的内存位置,一般用NULL或者kCFAllocatorDefault表示当前默认
CFSocketNativeHandle:之前创建的 native BSD socket
CFOptionFlags:关于回调的选项依次是kCFSocketNoCallBack/...ReadCallBack/...AcceptCallBack/...DataCallBack/...ConnectCallBack/...WriteCallBack
CFSocketCallBack:回调调用的函数,这是个c函数(acceptConnection方法)
CFSocketContext:并不知道有什么卵用
CFSocketCreateRunLoopSource的几个参数:
CFAllocatorRef:同上
CFSocketRef:之前通过BSD创建的那个
CFIndex:run loop中的优先级
CFRunLoopAddSource的参数:
CFRunLoopRef:所要添加进的run loop
CFRunLoopSourceRef:要加入的source
CFStringRed:run loop mode
将CFRunLoopSourceRef加入run loop后,清除掉不需要的内容
然后运行runloop
这里创建了一个新的CFSocketRef然后再加入另一个回调方法
将data先转成CFDataRef再转成UInt8再转成NSString
最后CFSocketSendData将CFDataRef格式的data发送出去
在通过BSD socket获取到listening descriptor后,通过CFSocketCreateWithNative()创建CFSocket,(这个步骤的逆向是CFSocketGetNative())然后将其加入run loop中
其实大家都知道BSD基本没有实用性,CFSocket还能用用
-(instancetype)initOnPort:(int)port { struct sockaddr_in servaddr; CFRunLoopSourceRef source; const CFSocketContext context = {0, NULL, NULL, NULL, NULL}; self.errorCode = NOERROR; if ((self.listenfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))<0) { self.errorCode = SOCKETERROR; } else { memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(port); if (bind(self.listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) <0) { self.errorCode = BINDERROR; } else { if (listen(self.listenfd, LISTENQ) <0) { self.errorCode = LISTENERROR; } else { self.sRef = CFSocketCreateWithNative(NULL, self.listenfd, kCFSocketAcceptCallBack, acceptConnection, &context); if (self.sRef == NULL) { self.errorCode = CFSOCKETCREATEERROR; }else { source = CFSocketCreateRunLoopSource(NULL, self.sRef, 0); CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode); CFRelease(source); CFRunLoopRun(); } } } } return self; }依次介绍下CFSocketCreateWithNative的几个参数:
CFAllocatorRef:用来定位新对象的内存位置,一般用NULL或者kCFAllocatorDefault表示当前默认
CFSocketNativeHandle:之前创建的 native BSD socket
CFOptionFlags:关于回调的选项依次是kCFSocketNoCallBack/...ReadCallBack/...AcceptCallBack/...DataCallBack/...ConnectCallBack/...WriteCallBack
CFSocketCallBack:回调调用的函数,这是个c函数(acceptConnection方法)
CFSocketContext:并不知道有什么卵用
CFSocketCreateRunLoopSource的几个参数:
CFAllocatorRef:同上
CFSocketRef:之前通过BSD创建的那个
CFIndex:run loop中的优先级
CFRunLoopAddSource的参数:
CFRunLoopRef:所要添加进的run loop
CFRunLoopSourceRef:要加入的source
CFStringRed:run loop mode
将CFRunLoopSourceRef加入run loop后,清除掉不需要的内容
CFRelease(source);
然后运行runloop
void acceptConnection(CFSocketRef sRef, CFSocketCallBackType cType, CFDataRef address, const void *data, void *info) { CFSocketNativeHandle csock = *(CFSocketNativeHandle *)data; CFSocketRef sn; CFRunLoopSourceRef source; const CFSocketContext context = {0, NULL, NULL, NULL, NULL}; sn = CFSocketCreateWithNative(NULL, csock, kCFSocketDataCallBack, receiveData, &context); source = CFSocketCreateRunLoopSource(NULL, sn, 0); CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode); CFRelease(source); CFRelease(sn); }
这里创建了一个新的CFSocketRef然后再加入另一个回调方法
void receiveData(CFSocketRef sRef, CFSocketCallBackType cType,CFDataRef address, const void *data, void *info) { CFDataRef df = (CFDataRef) data; long len = CFDataGetLength(df); if(len <= 0) return; UInt8 buf[len]; CFRange range = CFRangeMake(0,len); CFDataGetBytes(df, range, buf); buf[len]='\0'; NSString *str = [[NSString alloc] initWithData:(NSData*)data encoding:NSASCIIStringEncoding]; NSLog(@"Received: %@",str); [[NSNotificationCenter defaultCenter] postNotificationName:@"posttext" object:str]; CFSocketSendData(sRef, address, df, 0); // Echo back }
将data先转成CFDataRef再转成UInt8再转成NSString
最后CFSocketSendData将CFDataRef格式的data发送出去
相关文章推荐
- java-模拟tomcat服务器
- Linux socket 初步
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 不可修补的 iOS 漏洞可能导致 iPhone 4s 到 iPhone X 永久越狱
- iOS 12.4 系统遭黑客破解,漏洞危及数百万用户
- 每日安全资讯:NSO,一家专业入侵 iPhone 的神秘公司
- [转][源代码]Comex公布JailbreakMe 3.0源代码
- C#基于socket模拟http请求的方法
- 简单的Ruby中的Socket编程教程
- Socket不能选择本地IP连接问题如何解决
- C#之Socket操作类实例解析
- C#使用Socket快速判断数据库连接是否正常的方法
- 科学知识:理解socket
- php与flash as3 socket通信传送文件实现代码
- 解决time_wait强制关闭socket
- C#使用Socket上传并保存图片的方法
- 深入php socket的讲解与实例分析
- JavaScript Archive Network 集合