网络

来源:互联网 发布:python 遍历字符 编辑:程序博客网 时间:2024/06/09 20:22


NSURLConnection同步,异步与SSL 
http://qzc770707.blog.163.com/blog/static/3408275320105249566560/


通常在iPhone里用NSURLConnection做url请求

1.NSURLConnection同步与异步请求
(1)异步请求:
NSMutableData* buf = [[NSMutableData alloc] initWithLength:0];
NSURLConnection* connection = [[NSURLConnection alloc] initWithRequest:req delegate:self];
 
// 收到响应时, 会触发
- (void)connection:(NSURLConnection *)aConnection didReceiveResponse:(NSURLResponse *)aResponse;
// 可以在里面判断返回结果, 或者处理返回的http头中的信息
 
// 每收到一次数据, 会调用一次
- (void)connection:(NSURLConnection *)aConn didReceiveData:(NSData *)data;
// 因此一般来说,是
- (void)connection:(NSURLConnection *)aConn didReceiveData:(NSData *)data
{
    [buf appendData:data];
}
// buffer就是前面initWithRequest时同时声明的.
 
// 网络错误时触发
- (void)connection:(NSURLConnection *)aConn didFailWithError:(NSError *)error;
 
// 全部数据接收完毕时触发
- (void)connectionDidFinishLoading:(NSURLConnection *)aConn;


(2)同步请求:
/ 初始化請求
        NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];        
// 設置URL
        [request setURL:[NSURL URLWithString:urlStr]];
// 設置HTTP方法
        [request setHTTPMethod:@"GET"];
// 發送同步請求, 這裡得returnData就是返回得數據楽
        NSData *returnData = [NSURLConnection sendSynchronousRequest:request
                                                   returningResponse:nil error:nil];
// 釋放對象
        [request release];

 

 

2. 注意head请求,如果在head响应中继续请求下一个地址,之后的响应和前一个响应对象的指针地址一样,内容也一样。改为了get请求,解决此问题。还没有更彻底的解决办法。

   另外设置setCachePolicy不起作用。

 

3.ASIHTTPRequest.

   ASIHTTPRequest不是直接使用的NSURLConnection.

   ASIHTTPRequest is an easy to use wrapper around the CFNetwork API that makes some of the more tedious aspects of communicating with web servers easier. It is written in Objective-C and works in both Mac OS X and iPhone applications.


   http://allseeing-i.com/ASIHTTPRequest/

   http://www.cnblogs.com/chen1987lei/archive/2011/06/07/2074636.html

   ASIHttpRequest学习笔记(1):创建队列、下载请求、断点续传、解压缩

   http://ryan.easymorse.com/?p=12

ASIHTTPRequest系列(二):文件下载

   http://blog.csdn.net/kmyhy/archive/2011/06/03/6524916.aspx

   可能文件名下载文件的名称存在了头Content-Disposition中,在请求头响应中取得文件名,重新设置显示给用户的名称,及request setDownloadDestinationPath:downloadDestPathName];,但不要重新设置setTemporaryFileDownloadPath,必须在请求下载开始前设置setTemporaryFileDownloadPath,若请求开始后再重新设置,将导致ASIHTTPRequest找不到已下载的临时文件。可以将下载地址作为临时文件名,并且这样能更好的确保唯一性。

 

   队列异步请求中中获取或识别不同request小技巧
a,可以设置一个上下文(userInfo)到request对象中,当请求响应完后可以通过访问request对象的userInfo获取里面的信息
b,为每一个请求实例设置不同的setDidFinishSelector / setDidFailSelector的回调方法
c,继承ASIHTTPRequest,重写requestFinished: 与 failWithProblem:方法

 

   安全的内存回收建议
request并没有retain delegate,所以若在没有请求完时候释放此delegate,需要在dealloc方法里先取消所有请求,再释放请求实例,如

- (void)dealloc{[request clearDelegatesAndCancel];[request release];...[super dealloc];}



升级到iOS5后ASIHttpRequest库可能出现的问题及解决方法:
ASIAuthenticationDialog这个内置对话框在网络有代理的情况下出现,然后无论点cancle或是login都不能dismiss。在4.3的SDK中没问题,在5.0的SDK中会在Console中看到输出:

Unbalanced calls to begin/end appearance transitions for <ASIAutorotatingViewController:>

详见  http://sabolasi.iteye.com/blog/1296218

 http://www.cocoachina.com/iphonedev/sdk/2011/1021/3403.html

 或者到http://allseeing-i.com/ASIHTTPRequest/下载最新的版本。


3.1 ASIHTTPRequest 响应数据的编码

ASIHTTPRequest会尝试从头部的Content-Type字段读取接收到的数据的文本编码,如果它发现一个文本编码,它会设置字段responseEncoding为一个合适的 NSStringEncoding。如果它在头部字段没有发现一个文本编码,它会使用字段defaultResponseEncoding的默认值(这个字段默认值为NSISOLatin1StringEncoding)。

http://blog.csdn.net/workhardupc100/article/details/6941685


3.2.ASIHTTPRequest, 请求的其它特性
iOS4中,当应用后台运行时仍然请求数据:[request setShouldContinueWhenAppEntersBackground:YES ];
是否有网络请求:[ ASIHTTPRequest isNetworkInUse ]
是否显示网络请求信息在status bar上:[ ASIHTTPRequest setShouldUpdateNetworkActivityIndicator:NO ];
设置请求超时时,设置重试的次数:[ request setNumberOfTimesToRetryOnTimeout:2 ];
KeepAlive的支持:
// Set the amount of time to hang on to a persistent connection before it should expire to 2 minutes
[ request setPersistentConnectionTimeoutSeconds:120 ];
// Disable persistent connections entirely
[ request setShouldAttemptPersistentConnection:NO ];


ASIFormDataRequest addPostValue内部默认对值做url编码,所以不要在添加之前做url编码。

函数内容如下:

NSString *newString = [NSMakeCollectable(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)string, NULL, CFSTR(":/?#[]@!$ &'()*+,;=\"<>%{}|\\^~`"), CFStringConvertNSStringEncodingToEncoding([self stringEncoding]))) autorelease];


3.3设置Cookie,使用自己保存cookie的方式。ASI会自动把头键的首字母大写。

    [request setUseCookiePersistence:NO];
   // [ASIHTTPRequest setSessionCookies:nil];
    [request addRequestHeader:@"cookie" value:cookie];


3.4 ASIHTTPRequest默认超时时间

// The default number of seconds to use for a timeout
static NSTimeInterval defaultTimeOutSeconds = 10;

 

3.5在requestFinished中,取原请求地址要使用[request originUrl],因为当跳转时它内部会处理,[request url]返回的是最后跳转的地址了。

 

3.6

ASIHTTPRequest.m中- (BOOL)willRedirect函数中,

// Perhaps there are other headers we should be preserving, but it's hard to know what we need to keep and what to throw away.

上面这段话对应的代码在跳转时扔掉了大部分头,所以,写了一个类别重写这个方法,注掉了这段扔头的代码,使全部头都带上。


ASIHTTPRequest.m


4.iPhone 检查网络状态

   http://blog.csdn.net/xianpengliu/article/details/6569115

 

5.MKNetWorKit

MKNetWorkKit的出现给开发者带来了福音,它吸取了ASIHttpRequest与AFNetWorking的优点,并加入了自己特有的功能。
 
6.NSURL构造时,如果地址串上有unicode字符编码,结果为nil。

7.统计iPhone系统网络流量
 
 iPhone不能监测其他程序流量,只能监测本app
系统有相关api,但是是私有。SCNetWorkConnectCopyStatistice ?

 
有一种方法是,自己建立一个网络代理服务器,你的应用程序要做的就是下载一个配置文件,这个配置文件的功能就是更改本地的DNS地址,指向自己的网络代理服务器。然后所有的流量都是在网络代理服务器上进行统计,客户端只需要从你的DNS服务器上获取数据就行了!
其它的常规方法好像不行,至少目前ios不支持,因为你的应用程序是不能一直在后台运行的。


越狱后理论上可以实现,监听端口就可以了吧?

向运营商查询

看到一款名叫"彩虹流量"的软件,http://itunes.apple.com/in/app/id450995610?mt=8,他知道每个应用使用的流量的,同时还可以对数据进行压缩.
国外 Onavo 的模仿品,是的用的代理,数据经他服务器压缩过。其实移动平台上的网络访问大都用gzip压缩过,他再压缩,压缩率不会太高,甚至不做优化会使用网络访问变慢。

8.ASIHTTPRequest进度条
   ASIHTTPRequest提供两种进度条显示,简单进度条和精确进度条,使用showAccurateProgress来控制。
为一个request设置showAccurateProgress只会对该request有效。为一个队列设置 showAccurateProgress,会影响队列里所有的request。
使用简单进度条时,进度条只会在一个request完成时才更新。对于单个request,这意味着你只有两个进度状态:0%和100%。对于一个有5个request的队列 来说,有五个状态:0%,25%,50%,75%,100%,每个request完成时,进度条增长一次。
使用精确进度条时,每当字节被上传或下载时,进度条都会更新。它适用于上传/下载大块数据的请求,并且会更好的显示已经发送/接收的数据量。追踪上传会轻微降低界面效率,因为进度delegate(一般是UIProgressViews 或NSProgressIndicators)会更频繁地重绘。追踪下载会更影响界面效率,因为队列会先为每个GET型request进行HEAD请求,以便统计总下载量。
简单进度条(showAccurateProgress = NO)是ASINetworkQueue的默认值,适用于大量小数据请求。
精确进度条(showAccurateProgress = YES)是以同步方式执行的ASIHTTPRequest的默认值。
推荐对下载大文件的队列使用精确进度条,但是要避免对大量小数据请求使用精确进度条。

9.ASINetworkQueue
    imgDownloadNetworkQueue_=[[ASINetworkQueue alloc] init];
    imgDownloadNetworkQueue_.delegate=self;
    [imgDownloadNetworkQueue_ setMaxConcurrentOperationCount:1];
    [imgDownloadNetworkQueue_ setShouldCancelAllRequestsOnFailure:NO];
    imgDownloadNetworkQueue_.requestDidFinishSelector=@selector(requestFinished:);
    imgDownloadNetworkQueue_.requestDidFailSelector=@selector(requestFailed:);

注意:不要给ASINetworkQueue中的单个request设置delegate,而是设置ASINetworkQueue的requestDidFinishSelector和requestDidFailSelector。在销毁时调用
[imgDownloadNetworkQueue_ reset];
[imgDownloadNetworkQueue_ release];不会出现内存问题。

9.蓝牙
   苹果的官方api是不支持ios设备与ios设备的连接。不支持文件传输。
   官方的开发需要使用Gamekit.framework,#import <GameKit/GameKit.h>


10.AsyncSocket    
     iphone的标准推荐CFNetwork C库编程.但是编程比较烦躁

     AsyncSocket 官方网站:https://github.com/robbiehanson/CocoaAsyncSocket

10.1一些网络的基本概念

同步:指的是发送方不等接收方响应,便接着发下个数据包的通信方式;

异步:指发送方发出数据后,等收到接收方发回的响应,才发下一个数据包的通信方式

阻塞:指调用某函数时,直到该函数完成操作,才返回;否则一直阻塞在该调用上

非阻塞:指调用某操作时,不管操作是否成功都立即返回,而不会挂在该操作上

 

CAsyncSocket属于异步非阻塞类;

CSocket是MFC在CAsyncSocket基础上派生的一个同步阻塞Socket的封装类.

在didReadData事件里使用[socket readDataWithTimeout:-1 tag:0];就可以一直监听下去了。

当服务端主动关闭时,会依次调用

- (void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err;
- (void)onSocketDidDisconnect:(AsyncSocket *)sock;


11. ASIHTTPRequest的长连接,短连接

ASIHTTPRequest的GET方式采用的是connection: keep-alive(长连接方式),POST方式采用的是connection: close。

ASIHTTPRequest里面的Timeout的概念是例如若10秒服务器没有响应,客户端结束当前tcp连接。

request.shouldAttemptPersistentConnection = NO;(设置为不支持长连接)

HTTP持久连接(HTTP persistent connection,也称作HTTP keep-alive或HTTP connection reuse)是使用同一个TCP连接来发送和接收多个HTTP请求/应答,而不是为每一个新的请求/应答打开新的连接的方法。在请求服务没有及时响应的时候,客户端会在同一个tcp连接中再次请求服务器。导致的结果就是,客户端的现象:请求了一次。得到了一次response。 服务端收到两次请求,给出了一次返回。这里的“没有及时响应”,不是ASIHTTPRequest里面的Timeout的概念,应该是persistentConnectionTimeoutSeconds,这里是指服务端没有立刻发送确认ack的包。


12.

 

 

 


 

 

原创粉丝点击