ios开发 网络编程HTTP/FTP连接

1.CFHTTP

   可以使用CFHTTP API创建HTTP请求,通常HTTP请求方法包括GET、HEAD、PUT、POST、DELETE、TRACR、CONNECT和OPTIONS。使用CFHTTP请求一般4个步骤: 

 

  • 使用CFHTTPMessageCreateRequest函数生成一个CFHTTP消息对象
  • 使用CFHTTPMessageSetBody函数设置消息内容
  • 使用CFHTTPMessageSetHeaderFieldValue函数设置消息头
  • 使用CFHTTPMessageCopySerializedMessage序列化消息 
   只有http post 需要消息内容,里面是要提交的表单数据。

 

 

示例:创建一个http get请求,序列化后的请求应该通过写入流(write stream)发送。

CFStringRef requestHeader = CFSTR("Connection");

CFStringRef requestHeaderValue = CFSTR("close");

CFStringRef requestBody = CFSTR("");

 

CFStringRef url = CFSTR("http://www.baidu.com/");

CFStringRef requestMethod = CFSTR("GET");

 

CFURLRef requestURL = CFURLCreateWithString(kCFAllocatorDefault, url, NULL);

CFHTTPMessageRef request = CFHTTPMessageCreateRequest(kCFAllocatorDefault, requestMethod, requestURL, kCFHTTPVersion1_1);

CFHTTPMessageSetBody(request, requestBody);

CFHTTPMessageSetHeaderFieldValue(request, requestHeader, requestHeaderValue);

 

CFDataRef serializedRequest = CFHTTPMessageCopySerializedMessage(request);


 

      创建HTTP相应的步骤与创建请求的方法差不多,不同之处是用CFHTTPMessageCreateResponse函数代替CFHTTPMessageCreateRequest。

      可以使用一个CFReadStream对象来序列化并发送CFHTTP请求。当使用CFReadStream对象时,打开读取流的同时消息会被序列化并发送,这样可以方便地获取响应。如下:

  CFHTTPMessageRef request = CFHTTPMessageCreateRequest(kCFAllocatorDefault, requestMethod, requestURL, kCFHTTPVersion1_1);

  CFHTTPMessageSetBody(request, requestBody);

  CFHTTPMessageSetheaderFieldValue(request, requestHeader, requestHeaderValue);

  CFReadStreamRef readStream = CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, request);

  CFReadStreamOpen(readStream);

 

调用CFReadStreamCopyProperty 可以从读取流获取响应消息,代码如下:

CFHTTPMessageRef response = CFReadStreamCopyProperty(readStream, kCFStreamPropertyHTTPResponseHeader);

使用CFHTTPMessageCopyResponseStatusLine函数获得完整的状态行,如下:

CFStringRef statusLine = CFHTTPMessageCopyResponseStatusLine(response);

或者,使用CFHTTPMessageGetResponseStatusCode函数获取状态码,如下:

UInt32 errCode = CFHTTPMessageGetResponseStatusCode(response);

为了获取返回的数据,可以使用CFReadStreamSetClient方法设置回调函数,将readStream加到run loop中。在回调函数将每次读取的数据存起来(比如,有一个NSMutableData类型的变量data),读完后处理数据,代码如下:

if(kCFStreamEventHasBytesAvailable == eventType) 

{

UInt8 buff[255];

int length = CFReadStreamRead(stream, buff, 254);

[data appendBytes:buff  length:length]; 

if(kCFStreamEventEndEncountered == eventType) 

{

//读取已完成,处理读取的数据 

 

   如果接收数据是中文字符串,注意在创建NSString时选择编码,比如UTF8或GB2312编码,如下所示:

NSString *string = [[NSString alloc] initWithData:data encoding:0x80000632];//GB2312编码

   当使用CFReadStreamCreateForHTTPRequest创建读取流时,流的重定向默认是被禁止的。如果请求连接被重定向,会导致一个错误,它的状态码为300~307。如果收到一个重定向错误,需要关闭这个流,然后重新创建一个流,启用重定向并打开流。如下:

CFReadStreamRef readStream = CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, request);

if(CFReadStreamSetProperty(readStream, kCFStreamPropertyHTTPShouldAutoredirect, kCFBooleanTrue) == false)

{

//出错处理 

CFReadStreamOpen(myReadStream); 

 

2.CFFTP

  CFFTP也使用CFReadStream来传送FTP数据。使用CFReadStreamCreateWithFTPURL方法来创建FTP请求,这样会同时创建一个CFReadStreamRef对象来读取FTP服务器发送的数据,代码如下:

CFStringRef url = CFSTR("ftp://ftp.example.com/file.txt");

  CFURLRef requestURL = CFURLCreateWithString(kCFAllocatorDefault, url, NULL);

CFReadStreamRef readStream = CFReadStreamCreateWithFTPURL(kCFAllocatorDefault, requestURL);

       下一步,使用CFReadStreamSetClient方法设置回调函数来读取数据,然后把readStream加到程序的run loop中。

如果FTP需要使用用户名和密码认证,通过CFReadStreamSetProperty方法设置kCFStreamPropertyFTPUserName和kCFStreamPropertyFTPPassword属性。

要将文件下载到本地,可以使用CFWriteStreamCreateWithFile方法创建一个指向本地文件的写入流,将接收到的数据写入。

上传文件和下载文件差不多,只不过把读取流和写入流反过来用,使用CFWriteStreamCreateWithFTPURL方法创建写入流,使用CFReadStreamCreateWithFile创建读取流。

创建远程目录的方法与上传文件类似,只不过将CFURL对象设置一个路径而不是文件。

获取目录列表的方法与下载文件类似,数据读取到缓存后使用CFFTPCreateParsedResourceListing,方法对读取进行解析。

 

3.NSURLConnection

CFNetwork是比较底层的接口,虽然用起来比较灵活,但并不好用。多数程序仅仅需要创建简单的请求来获取互联网上的一个文件,那么使用NSURLConnection要更加方便,因为不用跟套接字、流还有回调函数打交道,取而代之的是更熟悉的委托机制。

       创建一个NSURL对象:

            NSNRL *url = [NSURL URLWithString:@"http://www.baidu.com/"];

       NSURL对象是用来创建NSURLRequest对象的,如下:

    NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url cachePolicy:NSURLRequestReturnCacheDataElseLoadtimeoutInterval:60.0];


 

可选的缓存策略有以下几种。

(1)NSURLRequestUseProtocolCachePolicy:使用相关协议默认缓存策略。

(2)NSURLRequestReloadIgnoringLocalCacheData: 无论本地缓存是什么,请求都要重新加载数据。

(3)NSURLRequestReloadIgnoringLocalAndRemoteCacheData:不仅要忽略本地缓存,在协议允许的情况下也要忽略远程代理或中间件的缓存。

(4)NSURLRequestReturnCacheDataElseLoad:优先使用缓存数据,缓存不存在时再去加载请求。

(5)NSURLRequestReturnCacheDataDontLoad:只加载缓存数据,缓存中不存在时也不请求,可理解为离线模式。

(6)NSURLRequestReloadRevalidatingCacheData: 缓存中的数据没有过期时才加载缓存中的数据,否则请求数据并刷新缓存。


 

 

     创建完NSURLRequest对象后就可以创建NSURLConnection对象了,如下:

NSURLConnection *connection = [[NSRULConnection alloc] initWithRequest:request delegate:self]; 

 

这个是异步调用,NSURLConnection会在后台发送请求,通过设置委托参数,有数据时会收到通知。由一些委托方法来处理连接是过程中的不同事件。

当服务主机有响应将要开始发送数据时,didReceiveResponse:方法会被调用。这里可以做一些初始化的工作,比如有一个NSMutableData类型的data对象来存储数据,在这里可以把对象长度设为0,如下所示

-(void) connection:(NSURLConnection *)connection didReceiveRespose:(NSURLResonse *)response 

{

[data setLength:0]; 

        } 

        当接收到数据时,didReceiveData:方法会被调用。这里可以把数据加到NSMutableData对象的后面,如下:

 - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)incomingData 

{

[data appendData:incomingData]; 

 

当数据加载完成时会调用connecitionDidFinshLoading:方法,处理传入的数据。这里以字符串处理为例,示例应用中传入的可能是图片或其他任何类型的对象。 

 

   - (void)connectionDidFinishLoading:(NSURLConnection *)connection

{
  NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(string);
[data release]; 
 
连接或传送数据失败时,didFailWithError方法会被调用,如下:
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(@"query failed with error:%@", [error localizedDescription]);
[data release];
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值