ImageVerifierCode 换一换
格式:DOCX , 页数:24 ,大小:94.04KB ,
资源ID:6868511      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/6868511.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(ios网络编程.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

ios网络编程.docx

1、ios网络编程iOS网络编程实践-NSStream实现TCP Socket iPhone客户端 客户端我们使用iPhone应用程序,画面比较简单。点击发送按钮,给服务器发送一些字符串过去。点击接收按钮就会从服务器读取一些字符串,并且显示在画面上。有关客户端应用的UI部分不再介绍了,我们直接看代码部分,Socket客户端可以采用CFStream或NSStream实现,CFStream 实现方式与服务器端基本一样。为了给读者介绍更多的知识,本例我们采用NSStream实现。NSStream实现采用Objective-C语言,一些 面向对象的类。下面我们看看客户端视图控制器ViewControlle

2、r.h#import #include #include #define PORT 9000 interface ViewController : UIViewControllerint flag ; /操作标志 0为发送 1为接收 property (nonatomic, retain) NSInputStream *inputStream;property (nonatomic, retain) NSOutputStream *outputStream; property (weak, nonatomic) IBOutlet UILabel *message; - (IBAction)se

3、ndData:(id)sender;- (IBAction)receiveData:(id)sender; end定义属性inputStream和outputStream,它们输入流NSInputStream和输出流NSOutputStream类。它们与服务器CFStream实现中的输入流CFReadStreamRef和输出流CFWriteStreamRef对应的。视图控制器ViewController.m的初始化网络方法initNetworkCommunication代码:- (void)initNetworkCommunicationCFReadStreamRef readStream;C

4、FWriteStreamRef writeStream;CFStreamCreatePairWithSocketToHost(NULL,(CFStringRef)”192.168.1.103, PORT, &readStream, &writeStream); _inputStream = (_bridge_transfer NSInputStream *)readStream; _outputStream = (_bridge_transfer NSOutputStream*)writeStream; _inputStream setDelegate:self; _outputStream

5、setDelegate:self; _inputStream scheduleInRunLoop:NSRunLoop currentRunLoopforMode:NSDefaultRunLoopMode; _outputStream scheduleInRunLoop:NSRunLoop currentRunLoopforMode:NSDefaultRunLoopMode; _inputStream open; _outputStream open; 点击发送和接收按钮触发的方法如下:/* 点击发送按钮 */- (IBAction)sendData:(id)sender flag = 0;se

6、lf initNetworkCommunication;/* 点击接收按钮 */- (IBAction)receiveData:(id)sender flag = 1;self initNetworkCommunication;它们都调用initNetworkCommunication方法,并设置操作标识flag,如果flag为0发送数据,flag为1接收数据。流的状态的变化触发很多事件,并回调NSStreamDelegate协议中定义的方法stream:handleEvent:,其代码如下:-(void)stream:(NSStream *)theStream handleEvent:(NS

7、StreamEvent)streamEvent NSString *event;switch (streamEvent) case NSStreamEventNone:event = ”NSStreamEventNone”;break;case NSStreamEventOpenCompleted:event = ”NSStreamEventOpenCompleted”;break;case NSStreamEventHasBytesAvailable:event = ”NSStreamEventHasBytesAvailable”;if (flag =1 & theStream = _inp

8、utStream) NSMutableData *input = NSMutableData alloc init;uint8_t buffer1024; int len;while(_inputStream hasBytesAvailable) len = _inputStream read:buffer maxLength:sizeof(buffer); if (len 0)input appendBytes:buffer length:len;NSString *resultstring = NSString allocinitWithData:input encoding:NSUTF8

9、StringEncoding;NSLog(”接收:%”,resultstring);_message.text = resultstring;break;case NSStreamEventHasSpaceAvailable:event = ”NSStreamEventHasSpaceAvailable”;if (flag =0 & theStream = _outputStream) /输出UInt8 buff = ”Hello Server!”; _outputStream write:buff maxLength: strlen(const char*)buff)+1; /关闭输出流_o

10、utputStream close;break;case NSStreamEventErrorOccurred:event = ”NSStreamEventErrorOccurred”;self close; break;case NSStreamEventEndEncountered:event = ”NSStreamEventEndEncountered”;NSLog(”Error:%d:%”,theStream streamError code,theStream streamError localizedDescription);break;default:self close; ev

11、ent = ”Unknown”;break;NSLog(”event%”,event);在读取数据分支(NSStreamEventHasBytesAvailable)中,代码第行为读取数据准备缓冲区,本例中设置的是1024个字节,这个大小会对流的读取有很多的影响。第行代码使用hasBytesAvailable方法判断是否流有数据可以读,如果有可读数据就进行循环读取。第行代码使用流的read:maxLength:方法读取数据到缓冲区,第1个参数是缓冲区对象buffer,第2个参数是读取的缓冲区的字节长度。在写入数据分支(NSStreamEventHasSpaceAvailable)中,代码第行是

12、要写入的数据,第行代码 _outputStreamwrite:buffmaxLength:strlen(constchar*)buff)+1是写如数据方 法。第和第行代码selfclose调用close方法关闭,close方法代码如下:-(void)close_outputStream close;_outputStream removeFromRunLoop:NSRunLoop currentRunLoopforMode:NSDefaultRunLoopMode;_outputStream setDelegate:nil;_inputStream close;_inputStream rem

13、oveFromRunLoop:NSRunLoop currentRunLoopforMode:NSDefaultRunLoopMode;_inputStream setDelegate:nil;深入浅出CocoaiOS网络编程之CFNetwork 深入浅出CocoaiOS网络编程之CFNetwork罗朝辉 (本文遵循“署名-非商业用途-保持一致”创作公用协议一,CFNetwork 简介首先来回顾下。在前文深入浅出CocoaiOS网络编程之Socket中,提到iOS网络编程层次模型分为三层: Cocoa层:NSURL,Bonjour,Game Kit,WebKit Core Foundation

14、层:基于 C 的CFNetwork 和 CFNetServices OS层:基于 C 的 BSD socket 前文讲的是最底层的 socket,本文将介绍位于 Core Foundation 中的 CFNetwork。CFNetwork 只是对 BSD socket 的进行了轻量级的封装,但在 iOS 中使用 CFNetwork 有一个显著的好处,那就是 CFNetwork 与系统级别的设置(如:天线设置)以及 run-loop 结合得很好。每一个线程都有自己的 run-loop,因此我们可以 CFNetwork 当中事件源加入到 run-loop 中,这样就可以在线程的 run-loop

15、中处理网络事件了。BTW,大名鼎鼎的 ASIHttpRequest 库就是基于 CFNetwork 封装的。本文示例代码就是这样做的,源码请查看:二,CFNetwork API 简介CFNetwork 接口是基于 C 的,下面的接口用于创建一对 socket stream,一个用于读取,一个用于写入:void CFStreamCreatePairWithSocketToHost(CFAllocatorRef alloc, CFStringRef host, UInt32 port, CFReadStreamRef *readStream, CFWriteStreamRef *writeStre

16、am);该函数使用 host 以及 port,CFNetwork 会将该 host 转换为 IP 地址,并转换为网络字节顺序。如果我们只需要一个 socket stream,我们可以将另外一个设置为 NULL。还有另外两个“重载”的创建 socket sream的接口:CFStreamCreatePairWithSocket 和CFStreamCreatePairWithPeerSocketSignature,在这里就不一一介绍了。注意:这些 socket stream 在使用之前就如原生 socket 一样,必须显式地调用其 open 函数:Boolean CFReadStreamOpen(

17、CFReadStreamRef stream);Boolean CFWriteStreamOpen(CFWriteStreamRef stream);但与 socket 不同的是,这两个接口是异步的,当成功 open 之后,如果调用方设置了获取kCFStreamEventOpenCompleted 事件的标志的话就会其调用回调函数。而该回调函数及其参数设置是通过如下接口进行的:Boolean CFReadStreamSetClient(CFReadStreamRef stream, CFOptionFlags streamEvents, CFReadStreamClientCallBack c

18、lientCB, CFStreamClientContext *clientContext);Boolean CFWriteStreamSetClient(CFWriteStreamRef stream, CFOptionFlags streamEvents, CFWriteStreamClientCallBack clientCB, CFStreamClientContext *clientContext);该函数用于设置回调函数及相关参数。通过streamEvents 标志来设置我们对哪些事件感兴趣;clientCB 是一个回调函数,当事件标志对应的事件发生时,该回调函数就会被调用;cli

19、entContext 是用于传递参数到回调函数中去。当设置好回调函数之后,我们可以将 socket stream 当做事件源调度到 run-loop 中去,这样 run-loop 就能分发该 socket stream 的网络事件了。void CFReadStreamScheduleWithRunLoop(CFReadStreamRef stream, CFRunLoopRef runLoop, CFStringRef runLoopMode);void CFWriteStreamScheduleWithRunLoop(CFWriteStreamRef stream, CFRunLoopRef

20、 runLoop, CFStringRef runLoopMode);注意,在我们不再关心该 socket stream 的网络事件时,记得要调用如下接口将 socket stream 从 run-loop 的事件源中移除。void CFReadStreamUnscheduleFromRunLoop(CFReadStreamRef stream, CFRunLoopRef runLoop, CFStringRef runLoopMode);void CFWriteStreamUnscheduleFromRunLoop(CFWriteStreamRef stream, CFRunLoopRef

21、runLoop, CFStringRef runLoopMode);当我们将 socket stream 的网络事件调度到 run-loop 之后,我们就能在回调函数中相应各种事件,比如kCFStreamEventHasBytesAvailable读取数据:Boolean CFReadStreamHasBytesAvailable(CFReadStreamRef stream);CFIndex CFReadStreamRead(CFReadStreamRef stream, UInt8 *buffer, CFIndex bufferLength);或kCFStreamEventCanAccep

22、tBytes 写入数据:Boolean CFWriteStreamCanAcceptBytes(CFWriteStreamRef stream);CFIndex CFWriteStreamWrite(CFWriteStreamRef stream, const UInt8 *buffer, CFIndex bufferLength);最后,我们调用 close 方法关闭 socket stream:void CFReadStreamClose(CFReadStreamRef stream);void CFWriteStreamClose(CFWriteStreamRef stream);三,客

23、户端示例代码与 socket 演示类似,在这里我只演示客户端示例。同样,我们也在一个后台线程中启动网络操作: NSURL * url = NSURL URLWithString:NSString stringWithFormat:%:%, serverHost, serverPort; NSThread * backgroundThread = NSThread alloc initWithTarget:self selector:selector(loadDataFromServerWithURL:) object:url; backgroundThread start;然后在loadDat

24、aFromServerWithURL 中创建 socket 流,并设置其回调函数,将其加入到 run-loop 的事件源中,然后启动之:- (void)loadDataFromServerWithURL:(NSURL *)url NSString * host = url host; NSInteger port = url port integerValue; / Keep a reference to self to use for controller callbacks / CFStreamClientContext ctx = 0, (_bridge void *)(self), N

25、ULL, NULL, NULL; / Get callbacks for stream data, stream end, and any errors / CFOptionFlags registeredEvents = (kCFStreamEventHasBytesAvailable | kCFStreamEventEndEncountered | kCFStreamEventErrorOccurred); / Create a read-only socket / CFReadStreamRef readStream; CFStreamCreatePairWithSocketToHost

26、(kCFAllocatorDefault, (_bridge CFStringRef)host, port, &readStream, NULL); / Schedule the stream on the run loop to enable callbacks / if (CFReadStreamSetClient(readStream, registeredEvents, socketCallback, &ctx) CFReadStreamScheduleWithRunLoop(readStream, CFRunLoopGetCurrent(), kCFRunLoopCommonMode

27、s); else self networkFailedWithErrorMessage:Failed to assign callback method; return; / Open the stream for reading / if (CFReadStreamOpen(readStream) = NO) self networkFailedWithErrorMessage:Failed to open read stream; return; CFErrorRef error = CFReadStreamCopyError(readStream); if (error != NULL)

28、 if (CFErrorGetCode(error) != 0) NSString * errorInfo = NSString stringWithFormat:Failed to connect stream; error % (code %ld), (_bridge NSString*)CFErrorGetDomain(error), CFErrorGetCode(error); self networkFailedWithErrorMessage:errorInfo; CFRelease(error); return; NSLog(Successfully connected to %

29、, url); / Start processing / CFRunLoopRun();参考前面的接口说明,相信你不难理解上面的代码。前面唯一没有提到的接口就是CFReadStreamCopyError,该接口用于获取当前的错误信息,如果没有错误则返回 NULL。CFErrorRef CFReadStreamCopyError(CFReadStreamRef stream);CFErrorRef CFWriteStreamCopyError(CFWriteStreamRef stream);此外,我们还可以调用如下接口获取 socket stream 的当前状态:CFStreamStatus

30、CFReadStreamGetStatus(CFReadStreamRef stream);CFStreamStatus CFWriteStreamGetStatus(CFWriteStreamRef stream);在上面的代码中,我们设置了当有数据可以读取,流到达结尾处时以及错误发生时调用回调函数socketCallback:void socketCallback(CFReadStreamRef stream, CFStreamEventType event, void * myPtr) KSCFNetworkViewController * controller = (_bridge KSCF

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1