1.为什么要使用网络?

People Lack Willpower,Rather Than Strength!

客户端和服务器之间如何通信?

  • 简而言之:

    • 客户端和服务器之间通信,由于使用不同语言编程,所以使用HTTP协议,完成双方数据交流;客户端以HTTP方式发送请求,服务器做出响应;
  • 常见请求发送方式:

    • NSURLConnection;
    • NSURLSession;
    • AFNetworking;
  • 发送请求步骤:

    // NSURLConnection:
    1.创建url;
    2.根据url创建request;
    3.使用NSURLConnection发送request;
    

HTTP

  • HTTP协议中向服务器发送请求的方法有多种,我们开发中常用的有get/post;
    • 1.get:处理纯粹获得资源的请求,同时,参数不能太大,不超过1KB;
    • 2.post:处理需要保密(简单保密),参数较大的请求

NSURLConnection

  • 发送请求步骤:

    // NSURLConnection:
    1.创建url;
    2.根据url创建request;
    3.使用NSURLConnection发送request;
    

  • 发送请求方式:

    • NSURLConnection中提供发送request的方案:
     1.sendSync....:主线程中进行,比较耗时,会阻塞;
     2.sendAsync...:在子线程中进行,可惜不能监控服务器返回的响应体中的data进度
     3.initWithRequest.....可以做到...监控进度,且是子线程.
     或者:connectionWithRequest....
    

  • NSURLRequest
    • 用于保存请求地址/请求头/请求体
    • 默认情况下NSURLRequest会自动给我们设置好请求头
    • request默认情况下就是GET请求

登录请求

  • get方法-------NSURLRequest同步/异步方法发送请求:
    /*=======================get同步方法发送request================================*/
- (void)sendSync
{
    // NSURLConnection-->http采用get请求|sendSync...方案发送请求

    // 1.创建URL
    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=520it&pwd=520it&type=JSON"];

    // 2.创建request
    // 默认情况下NSURLRequest会自动给我们设置好请求头
    // request默认情况下就是GET请求
    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    // 3.发送request
    /*
     第一个参数:需要请求的对象;
     第二个参数:服务返回给我们的响应头信息;
     第三个参数:错误信息;
     返回值:服务器返回给我们的响应体
     */
    //    NSURLResponse *response = nil;
    // response的真实类型是:
    NSHTTPURLResponse *response = nil;
    NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];

    // 打印响应头/体信息
    NSLog(@"%@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
    NSLog(@"%@",response.allHeaderFields);

    NSLog(@"touches...即将结束-------");

    /*
     2015-09-07 09:19:32.287 01-NSURLConnection基本使用[1116:143990] {"success":"登录成功"}
     2015-09-07 09:19:32.287 01-NSURLConnection基本使用[1116:143990] {
     "Content-Type" = "application/json;charset=UTF-8";
     Date = "Mon, 07 Sep 2015 01:19:29 GMT";
     Server = "Apache-Coyote/1.1";
     "Transfer-Encoding" = Identity;
     }
     2015-09-07 09:19:32.287 01-NSURLConnection基本使用[1116:143990] touches...即将结束-----
     */
}

/*============================get 异步方法发送request======================*/
- (void)sendAsync
{
    // 异步方法发送request
    // 1.创建URL
    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=520it&pwd=520it&type=JSON"];
    // 2.创建request
    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    // 3.异步发送request
    /*
     参数说明:
     参数一:需要请求的对象;
     参数二:回调block的队列,决定了block在哪个线程中执行;
     参数三:回调block(响应体句柄)
     */
    // 注意:如果这里是同步,会阻塞当前线程
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {

        /*
         response:响应头;
         data:响应体;
         connectionError:错误信息;
         */
        NSLog(@"%@",request.HTTPBody);
        NSLog(@"%@",request.allHTTPHeaderFields);
        /*
         2015-09-07 09:59:20.422 01-NSURLConnection基本使用[1425:362793] (null)
         2015-09-07 09:59:20.423 01-NSURLConnection基本使用[1425:362793] (null)
         为啥是NULL??😖
         */
        NSLog(@"%@",response);
        NSLog(@"%@",[NSThread currentThread]);
        NSLog(@"%@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
    }];



    NSLog(@"touches...即将结束-------");

    /*
     2015-09-07 09:15:42.689 01-NSURLConnection基本使用[1075:121037] touches...即将结束-------
     2015-09-07 09:15:42.731 01-NSURLConnection基本使用[1075:121037] <NSThread: 0x7fd649d19e20>{number = 1, name = main}
     2015-09-07 09:15:42.731 01-NSURLConnection基本使用[1075:121037] {"success":"登录成功"}
     */
}
  • 登录请求:请求头/体

    登录请求.png

  • post方法发送请求,这里以异步为例:

    // POST方法:可监控数据接收进度
        // 1.创建URL
        NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login"];
    
        // 2.创建request-->请求需要是可变类型
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
        // 设置请求方式
        request.HTTPMethod = @"POST"; // 这里一定要大写
        // httpbody:NSData类型
        // 注意: 如果是给POST请求传递参数: 那么不需要写?号,?只是get方法中参数与地址的分隔符!
        request.HTTPBody = [@"username=520it&pwd=520it&type=JSON" dataUsingEncoding:NSUTF8StringEncoding];
    
        // 3.发送请求
        [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
            NSLog(@"%@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
        }];
    
  • 中文问题

    • 说明:
      • 默认情况下,get方法,需要转码;

      • 默认情况下,post方法,不需要转码,因为参数放在请求体中,而且是以二进制形式:

         request.HTTPBody = [@"username=520it&pwd=520it&type=JSON" dataUsingEncoding:NSUTF8StringEncoding];
        
      • 开发中,考虑可能出错,一律转码.

        // get方法中的中文转码:
        - (void)get_sendAsync
        {
            // 请求中的中文问题
            // get方法--->要先转码❤️
            // 1.url
            NSString *urlStr = @"http://120.25.226.186:32812/login2?username=小码哥&pwd=520it&type=JSON";
            // 转码前
            NSLog(@"转码前---%@",urlStr);
            urlStr = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
            NSLog(@"转码后---%@",urlStr);
            NSURL *url = [NSURL URLWithString:urlStr];
        
            // 2.request
            NSURLRequest *request = [NSURLRequest requestWithURL:url];
            // 3.sendAsync
            [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
                NSLog(@"%@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
            }];
        
            /* 可见:get方法发送请求时,参数中不能有中文,需要转码
             2015-09-07 11:41:06.128 03-URL中文问题[2576:823835] 转码前---http://120.25.226.186:32812/login2?username=小码哥&pwd=520it&type=JSON
             2015-09-07 11:41:06.128 03-URL中文问题[2576:823835] 转码后---http://120.25.226.186:32812/login2?username=%E5%B0%8F%E7%A0%81%E5%93%A5&pwd=520it&type=JSON
             2015-09-07 11:41:06.201 03-URL中文问题[2576:823835] {"success":"登录成功"}
             */
        }
        //=======================================================
         // post方法--->无需转码❤️
            // 实际开发中,无论get/post都进行转码,省的更改.
            // 1.url
            NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login2"];
        
            // 2.request
            NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
            request.HTTPMethod = @"POST";
            // 这里将参数转换为二进制data,无需再转码!❤️
            request.HTTPBody = [@"username=小码哥&pwd=520it&type=JSON" dataUsingEncoding:NSUTF8StringEncoding]; // type可以不写
        
            // 3.sendAsync
            [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
                NSLog(@"%@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
            }];
        

下载请求

  • 说明:

    • 由于我们需要对下载过程进行监控,所以这里我们需要对NSURLConnection对象设置代理!
  • 下载请求步骤:

    • 1.url创建;
    • 2.request创建;
    • 3.创建connection,设置代理,执行request;
    • 4.实现代理方法;
  • 示例:

    • 1.request

      -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
      {
       // 通过initWithRequest.../connection方法发送请求,可以监控数据下载进度
       // 1.URL创建---->下载请求❤️
       NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/images/minion_02.png"];
      
       // 2.request创建
       NSURLRequest *request = [NSURLRequest requestWithURL:url];
      
       // 3.发送请求
       //    NSURLConnection *connect = [[NSURLConnection alloc] initWithRequest:request delegate:self];
       //    [NSURLConnection connectionWithRequest:request delegate:self];
       NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
       // 如果startImmediately:NO,则需要手动开启发动请求
       [connection start];
        //    NSLog(@"%@",connect);
       /*
      <NSURLConnection: 0x7f83c0716c70> 
        { request: <NSURLRequest: 0x7f83c0745600> { URL: http://120.25.226.186:32812/resources/images/minion_02.png } }
        // 可见这里不是我们想要下载的东西,可以不写
        */
      }
      
    • 2.代理方法

      // --------------------------------代理方法----------------------------
      #pragma mark - NSURLConnectionDataDelegate
      // 只要接收到服务器的响应就会调用
      // response:响应头
      - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
      {
       //    NSLog(@"%s", func);
        // 在此处,我们可以获得服务器返回给我们的文件总大小
        self.totalLength = response.expectedContentLength;
        // response中包含的属性含义:
        // 收到数据建议名字
        NSLog(@"%@",response.suggestedFilename);
        // 服务器响应数据大小
        NSLog(@"%lld",response.expectedContentLength);
        // 请求url
        NSLog(@"%@",response.URL);
        // 数据类型
        NSLog(@"%@",response.MIMEType);
      
        //     2015-09-07 11:06:40.240 02-NSURLConnection其他用法[2140:690910] minion_02.png
        //     2015-09-07 11:06:40.241 02-NSURLConnection其他用法[2140:690910] 43852
        //     2015-09-07 11:06:40.241 02-NSURLConnection其他用法[2140:690910] http://120.25.226.186:32812/resources/images/minion_02.png
        //     2015-09-07 11:06:40.241 02-NSURLConnection其他用法[2140:690910] image/png
      
         NSLog(@"%@",response);
        //    可见此处response包含两大部分内容:1.请求url;2.响应头;
        //     2015-09-07 10:59:48.113 02-NSURLConnection其他用法[1975:661374] <NSHTTPURLResponse: 0x7feadb7d5940> { URL: http://120.25.226.186:32812/resources/images/minion_02.png } { status code: 200, headers {
        //     "Accept-Ranges" = bytes;
        //     "Content-Length" = 43852;
        //     "Content-Type" = "image/png";
        //     Date = "Mon, 07 Sep 2015 02:42:51 GMT";
        //     Etag = "W/\"43852-1409456092000\"";
        //     "Last-Modified" = "Sun, 31 Aug 2014 03:34:52 GMT";
        //     Server = "Apache-Coyote/1.1";
        //     } }
        }
      
      // 接收到服务器返回的数据时调用(该方法可能调用一次,或者多次)
      // data:服务器返回的数据(是当前一次返回的,不是累积量)
      - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
      {
        //    NSLog(@"%s", func);
        self.currentLength += data.length;
        NSLog(@"%f",1.0 * self.currentLength / self.totalLength);
      }
      
      // 数据下载完成时调用
      - (void)connectionDidFinishLoading:(NSURLConnection *)connection
      {
        //    NSLog(@"%s", func);
        self.currentLength = 0;
      }
      
      // 请求错误时调用(请求超时)
      /*
      connection:didFailWithError: will be called at most once, if an error occurs during a resource load.  No other callbacks will be made after.<p>
      */
      - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
      {
        //    NSLog(@"%s", func);
      }
      /* 可见:服务器响应:响应头--->响应体-->下载完成
      2015-09-07 10:57:22.590 02-NSURLConnection其他用法[1939:649504] -[ViewController connection:didReceiveResponse:]
      2015-09-07 10:57:22.591 02-NSURLConnection其他用法[1939:649504] -[ViewController connection:didReceiveData:]
      2015-09-07 10:57:22.591 02-NSURLConnection其他用法[1939:649504] -[ViewController connectionDidFinishLoading:]
      */
      
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 207,113评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,644评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,340评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,449评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,445评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,166评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,442评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,105评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,601评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,066评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,161评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,792评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,351评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,352评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,584评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,618评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,916评论 2 344

推荐阅读更多精彩内容