ios网络编程Word文档下载推荐.docx

上传人:b****6 文档编号:19580712 上传时间:2023-01-08 格式:DOCX 页数:24 大小:94.08KB
下载 相关 举报
ios网络编程Word文档下载推荐.docx_第1页
第1页 / 共24页
ios网络编程Word文档下载推荐.docx_第2页
第2页 / 共24页
ios网络编程Word文档下载推荐.docx_第3页
第3页 / 共24页
ios网络编程Word文档下载推荐.docx_第4页
第4页 / 共24页
ios网络编程Word文档下载推荐.docx_第5页
第5页 / 共24页
点击查看更多>>
下载资源
资源描述

ios网络编程Word文档下载推荐.docx

《ios网络编程Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《ios网络编程Word文档下载推荐.docx(24页珍藏版)》请在冰豆网上搜索。

ios网络编程Word文档下载推荐.docx

(id)sender;

-(IBAction)receiveData:

@end

定义属性inputStream和outputStream,它们输入流NSInputStream和输出流NSOutputStream类。

它们与服务器CFStream实现中的输入流CFReadStreamRef和输出流CFWriteStreamRef对应的。

视图控制器ViewController.m的初始化网络方法initNetworkCommunication代码:

-(void)initNetworkCommunication

CFReadStreamRefreadStream;

CFWriteStreamRefwriteStream;

CFStreamCreatePairWithSocketToHost(NULL,

(CFStringRef)@”192.168.1.103″,PORT,&

readStream,&

writeStream);

_inputStream=(__bridge_transferNSInputStream*)readStream;

_outputStream=(__bridge_transferNSOutputStream*)writeStream;

[_inputStreamsetDelegate:

self];

[_outputStreamsetDelegate:

[_inputStreamscheduleInRunLoop:

[NSRunLoopcurrentRunLoop]

forMode:

NSDefaultRunLoopMode];

[_outputStreamscheduleInRunLoop:

[_inputStreamopen];

[_outputStreamopen];

点击发送和接收按钮触发的方法如下:

/*点击发送按钮*/

(id)sender{

flag=0;

[selfinitNetworkCommunication];

/*点击接收按钮*/

flag=1;

它们都调用initNetworkCommunication方法,并设置操作标识flag,如果flag为0发送数据,flag为1接收数据。

流的状态的变化触发很多事件,并回调NSStreamDelegate协议中定义的方法stream:

handleEvent:

,其代码如下:

-(void)stream:

(NSStream*)theStreamhandleEvent:

(NSStreamEvent)streamEvent{

NSString*event;

switch(streamEvent){

caseNSStreamEventNone:

event=@”NSStreamEventNone”;

break;

caseNSStreamEventOpenCompleted:

event=@”NSStreamEventOpenCompleted”;

caseNSStreamEventHasBytesAvailable:

event=@”NSStreamEventHasBytesAvailable”;

if(flag==1&

&

theStream==_inputStream){

NSMutableData*input=[[NSMutableDataalloc]init];

uint8_tbuffer[1024];

intlen;

while([_inputStreamhasBytesAvailable])②

len=[_inputStreamread:

buffermaxLength:

sizeof(buffer)];

if(len>

0)

[inputappendBytes:

bufferlength:

len];

NSString*resultstring=[[NSStringalloc]

initWithData:

inputencoding:

NSUTF8StringEncoding];

NSLog(@”接收:

%@”,resultstring);

_message.text=resultstring;

caseNSStreamEventHasSpaceAvailable:

event=@”NSStreamEventHasSpaceAvailable”;

if(flag==0&

theStream==_outputStream){

//输出

UInt8buff[]=”HelloServer!

”;

[_outputStreamwrite:

buffmaxLength:

strlen((constchar*)buff)+1];

//关闭输出流

[_outputStreamclose];

caseNSStreamEventErrorOccurred:

event=@”NSStreamEventErrorOccurred”;

[selfclose];

caseNSStreamEventEndEncountered:

event=@”NSStreamEventEndEncountered”;

NSLog(@”Error:

%d:

%@”,[[theStreamstreamError]code],

[[theStreamstreamError]localizedDescription]);

default:

event=@”Unknown”;

NSLog(@”event——%@”,event);

在读取数据分支(NSStreamEventHasBytesAvailable)中,代码第①行为读取数据准备缓冲区,本例中设置的是1024个字节,这个大小会对流的读取有很多的影响。

第②行代码使用hasBytesAvailable方法判断是否流有数据可以读,如果有可读数据就进行循环读取。

第③行代码使用流的read:

maxLength:

方法读取数据到缓冲区,第1个参数是缓冲区对象buffer,第2个参数是读取的缓冲区的字节长度。

在写入数据分支(NSStreamEventHasSpaceAvailable)中,代码第④行是要写入的数据,第⑤行代码[_outputStream 

write:

buff 

strlen((const 

char*)buff)+1]是写如数据方法。

第⑥和第⑦行代码[self 

close]调用close方法关闭,close方法代码如下:

-(void)close

[_outputStreamremoveFromRunLoop:

nil];

[_inputStreamclose];

[_inputStreamremoveFromRunLoop:

[深入浅出Cocoa]iOS网络编程之CFNetwork

[深入浅出Cocoa]iOS网络编程之CFNetwork

罗朝辉(

本文遵循“署名-非商业用途-保持一致”创作公用协议

一,CFNetwork简介

首先来回顾下。

在前文《[深入浅出Cocoa]iOS网络编程之Socket》中,提到iOS网络编程层次模型分为三层:

∙Cocoa层:

NSURL,Bonjour,GameKit,WebKit

∙CoreFoundation层:

基于C的 

CFNetwork和CFNetServices

∙OS层:

基于C的BSDsocket

前文讲的是最底层的socket,本文将介绍位于CoreFoundation中的CFNetwork。

CFNetwork只是对BSDsocket的进行了轻量级的封装,但在iOS中使用CFNetwork有一个显著的好处,那就是CFNetwork与系统级别的设置(如:

天线设置)以及run-loop结合得很好。

每一个线程都有自己的run-loop,因此我们可以CFNetwork当中事件源加入到run-loop中,这样就可以在线程的run-loop中处理网络事件了。

BTW,大名鼎鼎的ASIHttpRequest库就是基于CFNetwork封装的。

本文示例代码就是这样做的,源码请查看:

二,CFNetworkAPI简介

CFNetwork接口是基于C的,下面的接口用于创建一对socketstream,一个用于读取,一个用于写入:

voidCFStreamCreatePairWithSocketToHost(CFAllocatorRefalloc,CFStringRefhost,UInt32port,CFReadStreamRef*readStream,CFWriteStreamRef*writeStream);

该函数使用host以及port,CFNetwork会将该host转换为IP地址,并转换为网络字节顺序。

如果我们只需要一个socketstream,我们可以将另外一个设置为NULL。

还有另外两个“重载”的创建socketsream的接口:

CFStreamCreatePairWithSocket和 

CFStreamCreatePairWithPeerSocketSignature,在这里就不一一介绍了。

注意:

这些socketstream在使用之前就如原生socket一样,必须显式地调用其open函数:

BooleanCFReadStreamOpen(CFReadStreamRefstream);

BooleanCFWriteStreamOpen(CFWriteStreamRefstream);

但与socket不同的是,这两个接口是异步的,当成功open之后,如果调用方设置了获取 

kCFStreamEventOpenCompleted事件的标志的话就会其调用回调函数。

而该回调函数及其参数设置是通过如下接口进行的:

BooleanCFReadStreamSetClient(CFReadStreamRefstream,CFOptionFlagsstreamEvents,CFReadStreamClientCallBackclientCB,CFStreamClientContext*clientContext);

BooleanCFWriteStreamSetClient(CFWriteStreamRefstream,CFOptionFlagsstreamEvents,CFWriteStreamClientCallBackclientCB,CFStreamClientContext*clientContext);

该函数用于设置回调函数及相关参数。

通过 

streamEvents标志来设置我们对哪些事件感兴趣;

clientCB是一个回调函数,当事件标志对应的事件发生时,该回调函数就会被调用;

clientContext是用于传递参数到回调函数中去。

当设置好回调函数之后,我们可以将socketstream当做事件源调度到run-loop中去,这样run-loop就能分发该socketstream的网络事件了。

voidCFReadStreamScheduleWithRunLoop(CFReadStreamRefstream,CFRunLoopRefrunLoop,CFStringRefrunLoopMode);

voidCFWriteStreamScheduleWithRunLoop(CFWriteStreamRefstream,CFRunLoopRefrunLoop,CFStringRefrunLoopMode);

注意,在我们不再关心该socketstream的网络事件时,记得要调用如下接口将socketstream从run-loop的事件源中移除。

voidCFReadStreamUnscheduleFromRunLoop(CFReadStreamRefstream,CFRunLoopRefrunLoop,CFStringRefrunLoopMode);

voidCFWriteStreamUnscheduleFromRunLoop(CFWriteStreamRefstream,CFRunLoopRefrunLoop,CFStringRefrunLoopMode);

当我们将socketstream的网络事件调度到run-loop之后,我们就能在回调函数中相应各种事件,比如 

kCFStreamEventHasBytesAvailable 

读取数据:

BooleanCFReadStreamHasBytesAvailable(CFReadStreamRefstream);

CFIndexCFReadStreamRead(CFReadStreamRefstream,UInt8*buffer,CFIndexbufferLength);

或 

kCFStreamEventCanAcceptBytes写入数据:

BooleanCFWriteStreamCanAcceptBytes(CFWriteStreamRefstream);

CFIndexCFWriteStreamWrite(CFWriteStreamRefstream,constUInt8*buffer,CFIndexbufferLength);

最后,我们调用close方法关闭socketstream:

voidCFReadStreamClose(CFReadStreamRefstream);

voidCFWriteStreamClose(CFWriteStreamRefstream);

三,客户端示例代码

与socket演示类似,在这里我只演示客户端示例。

同样,我们也在一个后台线程中启动网络操作:

NSURL*url=[NSURLURLWithString:

[NSStringstringWithFormat:

@"

%@:

%@"

serverHost,serverPort]];

NSThread*backgroundThread=[[NSThreadalloc]initWithTarget:

self

selector:

@selector(loadDataFromServerWithURL:

object:

url];

[backgroundThreadstart];

然后在 

loadDataFromServerWithURL中创建socket流,并设置其回调函数,将其加入到run-loop的事件源中,然后启动之:

-(void)loadDataFromServerWithURL:

(NSURL*)url

NSString*host=[urlhost];

NSIntegerport=[[urlport]integerValue];

//Keepareferencetoselftouseforcontrollercallbacks

//

CFStreamClientContextctx={0,(__bridgevoid*)(self),NULL,NULL,NULL};

//Getcallbacksforstreamdata,streamend,andanyerrors

CFOptionFlagsregisteredEvents=(kCFStreamEventHasBytesAvailable|kCFStreamEventEndEncountered|kCFStreamEventErrorOccurred);

//Createaread-onlysocket

CFReadStreamRefreadStream;

CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault,(__bridgeCFStringRef)host,port,&

readStream,NULL);

//Schedulethestreamontherunlooptoenablecallbacks

if(CFReadStreamSetClient(readStream,registeredEvents,socketCallback,&

ctx)){

CFReadStreamScheduleWithRunLoop(readStream,CFRunLoopGetCurrent(),kCFRunLoopCommonModes);

}

else{

[selfnetworkFailedWithErrorMessage:

Failedtoassigncallbackmethod"

];

return;

//Openthestreamforreading

if(CFReadStreamOpen(readStream)==NO){

Failedtoopenreadstream"

CFErrorReferror=CFReadStreamCopyError(readStream);

if(error!

=NULL){

if(CFErrorGetCode(error)!

=0){

NSString*errorInfo=[NSStringstringWithFormat:

Failedtoconnectstream;

error'

%@'

(code%ld)"

(__bridgeNSString*)CFErrorGetDomain(error),CFErrorGetCode(error)];

errorInfo];

CFRelease(error);

NSLog(@"

Successfullyconnectedto%@"

url);

//Startprocessing

CFRunLoopRun();

参考前面的接口说明,相信你不难理解上面的代码。

前面唯一没有提到的接口就是 

CFReadStreamCopyError,该接口用于获取当前的错误信息,如果没有错误则返回NULL。

CFErrorRefCFReadStreamCopyError(CFReadStreamRefstream);

CFErrorRefCFWriteStreamCopyError(CFWriteStreamRefstream);

此外,我们还可以调用如下接口获取socketstream的当前状态:

CFStreamStatusCFReadStreamGetStatus(CFReadStreamRefstream);

CFStreamStatusCFWriteStreamGetStatus(CFWriteStreamRefstream);

在上面的代码中,我们设置了当有数据可以读取,流到达结尾处时以及错误发生时调用回调函数 

socketCallback:

voidsocketCallback(CFReadStreamRefstream,CFStreamEventTypeevent,void*myPtr)

KSCFNetworkViewController*controller=(__bridgeKSCF

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > PPT模板 > 其它模板

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

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