http编程综述:亦可称为soap编程。通常情况下,http编程要比socket编程相对要简单易用得多。所以用的最广广泛。
一、http编程其实就是http请求。http请求最长用的方法是 get 和 post 方法。
==》get方法和post方法相比理解起来比较简单,get方法可以直接请求一个url,也可以url后面拼接上参数作为一个新的url地址进行请求。get方法后面的value要经过unicode编码。form的enctype属性默认为application/x-www-form-urlencoded。不能发送二进制文件。
==》post方法相对要复杂一些。首先post方法要设置key和value ,所有的key和value都会拼接成 key1=value1&key2=value2的样式的字符串,然后这个字符串转化为二进制放到 http请求的body中。当请求发送的时候,也就跟随body一起传给服务器。http请求Content-Type设置为:application/x-www-form-urlencoded。这里讲的只是简单的post请求,一般发送文件不会选择这种方式(从技术方面考虑也可以发送文件,就是把文件以 key 和 value的方式放入)。下面我们再讨论一下post发送二进制文件更加普遍的方法。
==》post方法相对要复杂一些。首先post方法要设置key和value ,所有的key和value都会拼接成 key1=value1&key2=value2的样式的字符串,然后这个字符串转化为二进制放到 http请求的body中。当请求发送的时候,也就跟随body一起传给服务器。http请求Content-Type设置为:application/x-www-form-urlencoded。这里讲的只是简单的post请求,一般发送文件不会选择这种方式(从技术方面考虑也可以发送文件,就是把文件以 key 和 value的方式放入)。下面我们再讨论一下post发送二进制文件更加普遍的方法。
二、HTTP协议是什么?
简单来说,就是一个基于应用层的通信规范:双方要进行通信,大家都要遵守一个规范,这个规范就是HTTP协议。
HTTP协议能做什么?
很多人首先一定会想到:浏览网页。没错,浏览网页是HTTP的主要应用,但是这并不代表HTTP就只能应用于网页的浏览。HTTP是一种协议,只要通信的双方都遵守这个协议,HTTP就能有用武之地。比如咱们常用的QQ,迅雷这些软件,都会使用HTTP协议(还包括其他的协议)。
HTTP协议如何工作?
大家都知道一般的通信流程:首先客户端发送一个请求(request)给服务器,服务器在接收到这个请求后将生成一个响应(response)返回给客户端。
在这个通信的过程中HTTP协议在以下4个方面做了规定:
简单来说,就是一个基于应用层的通信规范:双方要进行通信,大家都要遵守一个规范,这个规范就是HTTP协议。
HTTP协议能做什么?
很多人首先一定会想到:浏览网页。没错,浏览网页是HTTP的主要应用,但是这并不代表HTTP就只能应用于网页的浏览。HTTP是一种协议,只要通信的双方都遵守这个协议,HTTP就能有用武之地。比如咱们常用的QQ,迅雷这些软件,都会使用HTTP协议(还包括其他的协议)。
HTTP协议如何工作?
大家都知道一般的通信流程:首先客户端发送一个请求(request)给服务器,服务器在接收到这个请求后将生成一个响应(response)返回给客户端。
在这个通信的过程中HTTP协议在以下4个方面做了规定:
1. Request和Response的格式()
2. 建立连接的方式(1、非持久连接 2、持久连接)
3. 缓存的机制
4. 响应授权激发机制
2. 建立连接的方式(1、非持久连接 2、持久连接)
3. 缓存的机制
4. 响应授权激发机制
(应用场合)
5. 基于HTTP的应用(1、 HTTP代理 2、多线程下载 3、 HTTPS传输协议原理 4、开发web程序时常用的Request Methods 5、用户与服务器的交互)
5. 基于HTTP的应用(1、 HTTP代理 2、多线程下载 3、 HTTPS传输协议原理 4、开发web程序时常用的Request Methods 5、用户与服务器的交互)
常用cocoa内部类:
1,Reachability.h 苹果demo支持网络连接诊断
2,NSConnection连接、NSMutableURLRequest URL网址的请求封装包
3,NSXMLParser XML解析
常用第三方库:
1,ASIHttprequest 库
操作步骤:
1:检查网络环境(3G/WIFI)
2:发起NSConnection请求
3:处理返回xml数据包(NSXMLParser解析xml文件),或者返回文件png、pdf之类
4:若返回数据包中含有待下载的图片下载地址。则重复2、3步骤下载下来图片。只不过3中返回的是文件。
socket编程综述:
2:发起NSConnection请求
3:处理返回xml数据包(NSXMLParser解析xml文件),或者返回文件png、pdf之类
4:若返回数据包中含有待下载的图片下载地址。则重复2、3步骤下载下来图片。只不过3中返回的是文件。
socket编程综述:
常用cocoa内部类:
常用第三方库:1,Asyncsocket库
操作步骤:
http网络编程实例
一:确认网络环境3G/WIFI1. 添加源文件和framework
开发Web等网络应用程序的时候,需要确认网络环境,连接情况等信息。如果没有处理它们,是不会通过Apple的审查的。
Apple 的 例程 Reachability 中介绍了取得/检测网络状态的方法。要在应用程序程序中使用Reachability,首先要完成如下两部:
1.1. 添加源文件:
在你的程序中使用 Reachability 只须将该例程中的 Reachability.h 和 Reachability.m 拷贝到你的工程中。如下图:
1.2.添加framework:
将SystemConfiguration.framework 添加进工程。如下图:
2. 网络状态
Reachability.h中定义了三种网络状态:
typedef enum {
NotReachable = 0, //无连接
ReachableViaWiFi, //使用3G/GPRS网络
ReachableViaWWAN //使用WiFi网络
} NetworkStatus;
因此可以这样检查网络状态:
Reachability *r = [Reachability reachabilityWithHostName:@“ www.apple.com”];
switch ([r currentReachabilityStatus]) {
case NotReachable:
// 没有网络连接
break;
case ReachableViaWWAN:
// 使用3G网络
break;
case ReachableViaWiFi:
// 使用WiFi网络
break;
}
3.检查当前网络环境
程序启动时,如果想检测可用的网络环境,可以像这样
// 是否wifi
+ (BOOL) IsEnableWIFI {
return ([[Reachability reachabilityForLocalWiFi] currentReachabilityStatus] != NotReachable);
}
// 是否3G
+ (BOOL) IsEnable3G {
return ([[Reachability reachabilityForInternetConnection] currentReachabilityStatus] != NotReachable);
}
例子:
- (void)viewWillAppear:(BOOL)animated {
if (([Reachability reachabilityForInternetConnection].currentReachabilityStatus == NotReachable) &&
([Reachability reachabilityForLocalWiFi].currentReachabilityStatus == NotReachable)) {
self.navigationItem.hidesBackButton = YES;
[self.navigationItem setLeftBarButtonItem:nil animated:NO];
}
}
4. 链接状态的实时通知
网络连接状态的实时检查,通知在网络应用中也是十分必要的。接续状态发生变化时,需要及时地通知用户:
Reachability 1.5版本
// My.AppDelegate.h
#import "Reachability.h"
@interface MyAppDelegate : NSObject <UIApplicationDelegate> {
NetworkStatus remoteHostStatus;
}
@property NetworkStatus remoteHostStatus;
@end
// My.AppDelegate.m
#import "MyAppDelegate.h"
@implementation MyAppDelegate
@synthesize remoteHostStatus;
// 更新网络状态
- (void)updateStatus {
self.remoteHostStatus = [[Reachability sharedReachability] remoteHostStatus];
}
// 通知网络状态
- (void)reachabilityChanged:(NSNotification *)note {
[self updateStatus];
if (self.remoteHostStatus == NotReachable) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"AppName", nil)
message:NSLocalizedString (@"NotReachable", nil)
delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
[alert show];
[alert release];
}
}
// 程序启动器,启动网络监视
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// 设置网络检测的站点
[[Reachability sharedReachability] setHostName:@"www.apple.com"];
[[Reachability sharedReachability] setNetworkStatusNotificati*****Enabled:YES];
// 设置网络状态变化时的通知函数
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reachabilityChanged:)
name:@"kNetworkReachabilityChangedNotification" object:nil];
[self updateStatus];
}
- (void)dealloc {
// 删除通知对象
[[NSNotificationCenter defaultCenter] removeObserver:self];
[window release];
[super dealloc];
}
Reachability 2.0版本
// MyAppDelegate.h
@class Reachability;
@interface MyAppDelegate : NSObject <UIApplicationDelegate> {
Reachability *hostReach;
}
@end
// MyAppDelegate.m
- (void)reachabilityChanged:(NSNotification *)note {
Reachability* curReach = [note object];
NSParameterAssert([curReach isKindOfClass: [Reachability class]]);
NetworkStatus status = [curReach currentReachabilityStatus];
if (status == NotReachable) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"AppName""
message:@"NotReachable"
delegate:nil
cancelButtonTitle:@"YES" otherButtonTitles:nil];
[alert show];
[alert release];
}
}
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// ...
// 监测网络情况
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(reachabilityChanged:)
name: kReachabilityChangedNotification
object: nil];
hostReach = [[Reachability reachabilityWithHostName:@"www.google.com"] retain];
hostReach startNotifer];
// ...
}
二:使用NSConnection下载数据
1.创建NSConnection对象,设置委托对象
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[self urlString]]];
[NSURLConnection connectionWithRequest:request delegate:self];
2. NSURLConnection delegate委托方法
- (void)connection:(NSURLConnection *)connection didReceiveResp*****e:(NSURLResp*****e *)resp*****e;
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;
- (void)connectionDidFinishLoading:(NSURLConnection *)connection;
3. 实现委托方法
- (void)connection:(NSURLConnection *)connection didReceiveResp*****e:(NSURLResp*****e *)resp*****e {
// store data
[self.receivedData setLength:0]; //通常在这里先清空接受数据的缓存
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
/* appends the new data to the received data */
[self.receivedData appendData:data]; //可能多次收到数据,把新的数据添加在现有数据最后
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
// 错误处理
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
// disconnect
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
NSString *returnString = [[NSString alloc] initWithData:self.receivedData encoding:NSUTF8StringEncoding];
NSLog(returnString);
[self urlLoaded:[self urlString] data:self.receivedData];
firstTimeDownloaded = YES;
}
三:使用NSXMLParser解析xml文件
1. 设置委托对象,开始解析
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data]; //或者也可以使用initWithContentsOfURL直接下载文件,但是有一个原因不这么做:
// It's also possible to have NSXMLParser download the data, by passing it a URL, but this is not desirable
// because it gives less control over the network, particularly in responding to connection errors.
[parser setDelegate:self];
[parser parse];
2. 常用的委托方法
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
attributes:(NSDictionary *)attributeDict;
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName;
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string;
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError;
static NSString *feedURLString = @"http://www.yifeiyang.net/test/test.xml";
3. 应用举例
- (void)parseXMLFileAtURL:(NSURL *)URL parseError:(NSError **)error
{
NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:URL];
[parser setDelegate:self];
[parser setShouldProcessNamespaces:NO];
[parser setShouldReportNamespacePrefixes:NO];
[parser setShouldResolveExternalEntities:NO];
[parser parse];
NSError *parseError = [parser parserError];
if (parseError && error) {
*error = parseError;
}
[parser release];
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString*)qName attributes:(NSDictionary *)attributeDict{
// 元素开始句柄
if (qName) {
elementName = qName;
}
if ([elementName isEqualToString:@"user"]) {
// 输出属性值
NSLog(@"Name is %@ , Age is %@", [attributeDict objectForKey:@"name"], [attributeDict objectForKey:@"age"]);
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
{
// 元素终了句柄
if (qName) {
elementName = qName;
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
// 取得元素的text
}
NSError *parseError = nil;
[self parseXMLFileAtURL:[NSURL URLWithString:feedURLString] parseError:&parseError];
//实例
//
// NLViewController.m
// NetWorkTest
//
// Created by Nono on 12-5-16.
// Copyright (c) 2012年 NonoWithLilith. All rights reserved.
//
#import "NLViewController.h"
@interface NLViewController ()
@end
@implementation NLViewController
@synthesize label = _label;
@synthesize data = _data;
@synthesize connection = _connection;
- (void)dealloc{
[self.label release];
[self.data release];
[super dealloc];
}
- (void)viewDidLoad
{
[super viewDidLoad];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10.0, 10.0, 300.0, 400)];
self.label = label;
label.textAlignment = UITextAlignmentCenter;
[label setNumberOfLines:0];
label.lineBreakMode = UILineBreakModeWordWrap;
self.label.text = @"正在在请求数据";
[self.view addSubview:label];
[label release];
//step 1:请求地址
NSString *urlString = @"http://www.google.com";
NSURL *url = [NSURL URLWithString:urlString];
//step 2:实例化一个request
NSURLRequest *requrst = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30.0];
//step 3:创建链接
self.connection = [[NSURLConnection alloc] initWithRequest:requrst delegate:self];
if ( self.connection) {
NSLog(@"链接成功");
}else {
NSLog(@"链接失败");
}
[url release];
[urlString release];
[requrst release];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidUnload
{
self.label = nil;
self.data = nil;
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
#pragma mark-
#pragma NSUrlConnectionDelegate methods
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
//接受一个服务端回话,再次一般初始化接受数据的对象
NSLog(@"返回数据类型:%@",[response textEncodingName]);
NSMutableData *d = [[NSMutableData alloc] init];
self.data = d;
[d release];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
//接受返回数据,这个方法可能会被调用多次,因此将多次返回数据加起来
NSUInteger datalength = [data length];
NSLog(@"返回数据量:%d",datalength);
[self.data appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
//连接结束
NSLog(@"%d:",[self.data length]);
NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
NSString *mystr = [[NSString alloc] initWithData:_data encoding:enc];
// string i
NSLog(@"最后的结果:%@",mystr);
self.label.text = mystr;
[mystr release];
[self.connection release];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
//链接错误
}
@end