[New learn] 网络基础-网络操作

代码:https://github.com/xufeng79x/NETOperation

1.简介

  主要记录基本的网络操作步骤,get/post关系和区别和文件上传实现。

2.准备

  需要服务器端,如果你没有完成服务器端的操作请参考[New learn] 网络基础-apache本地服务搭建(支持php)

3.网络基本操作

3.1.基本操作步骤

  //step_1:创建URL

  //step_2:创建request

  //step_3:建立连接接受返回数据

  //step_4:反序列化数据

举例:如下我们将按照此步骤从网络上下载图片显示在UI上。

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    [self downloadFile];
}

-(void)downloadFile
{
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];
    [queue addOperationWithBlock:^{
        //step_1:创建URL
        NSString *urlStr = @"http://imgsrc.baidu.com/forum/pic/item/645b8701a18b87d6e716e197070828381e30fdae.jpg";
        NSURL *url = [NSURL URLWithString:urlStr];

        //step_2:创建request
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:0 timeoutInterval:2.0f];

        //step_3:建立连接接受返回数据
        [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {

            // step_4:反序列化数据
            UIImage *image = [[UIImage alloc]initWithData:data];

            // 设定UI显示
            self.imageView.image = image;
        }];

    }];
}

结果:

说明:这里只是快速演示了一个网络请求的过程,无论后续讲到的get、post该是文件上传等都不脱离这个大的过程,无非是细节的不同罢了。

3.2 网络操作过程原理

一般网络请求方式分为多种,但是我们最常用的只有GET和POST两种(默认为GET),这两者的区别和使用场景及原理本文后续会涉及。

客户端与服务端的通信原理如下图:

              

上图中,GET操作是没有请求体的,那的所有参数都放在了URL(请求行)中,而对于POST操作则没有URL参数这个说法而是将所有的参数(包括文件的二进制内容)都放在请求体中。

GET

例如我们访问:http://127.0.0.1/login 在GET 请求演示中输入正确的用户名和密码:xf/ios

                    

点击URL后在地址栏中出现了我们输入的内容:

                    

请求行与请求头:

                    

                    上述红框中的为请求行,它指明了协议,方式(GET)和URL。其余部分为请求头

                    对于相应部分可以自行测试观察。        

总结:我们可以看到GET方式它的参数都是在URL中显式指定的,对于用户名和密码这个场景来说显然就不适合了。这样的场景下我们可以POST方式更为妥当。

POST

例如我们访问:http://127.0.0.1/login 在POST 请求演示中输入正确的用户名和密码:xf/ios

                    

点击URL后在地址栏中并没有出现用户名和密码:

                    

请求行与请求头:

                    

                    上述红框中的为请求行,它指明了协议,方式(GET)和URL。其余部分为请求头

                    对于相应部分可以自行测试观察。

请求体:

        

总结:我们可以看到POST方式指定的,用户名和密码不会出现在URL中,然是被包装进了请求体中,同时这些用户信息也不会被服务器端的日志所记录。

3.3 网络操作过程代码实现

进过上述过程已经对网络的原理有了简单地认识,并且我们也通过浏览器进行了两种方式的操作,而使用代码来实现无非是借助于框架的API来模拟还原这个过程。

GET

代码:

- (void)getLogin
{

    // step_1:创建URL
    NSString *username = @"xf";
    NSString *pwd = @"ios";
    NSString *urlString = [NSString stringWithFormat:@"http://127.0.0.1/login.php?username=%@&password=%@",username, pwd];
    NSURL *url = [NSURL URLWithString:urlString];

    // step_2:创建request
    NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:1 timeoutInterval:2.0f];

    // step_3:建立连接接受返回数据
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {

        // 反序列化
        id result = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];

        NSLog(@"%@", result);
    }];
}

结果:可以看到与浏览器返回的数据是一致的。

2016-03-15 15:52:59.779 NetOperation[1594:117149] {
    userId = 1;
    userName = xufeng;
}

总结:GET操作的时候无非就是去将参数拼接进URL,通过这个URL去获取数据

POST

代码:

- (void)postLogin
{

    // step_1:创建URL
    NSString *urlString = @"http://127.0.0.1/login.php";
    NSURL *url = [NSURL URLWithString:urlString];

    // step_2:创建request
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:1 timeoutInterval:2.0f];

    // 2.1 指定http的访问方法,服务器短才知道如何访问
    request.HTTPMethod = @"POST";

    // 2.2 指定数据体,数据体的内容可以从firebug里面直接拷贝
    NSString *username = @"xf";
    NSString *pwd = @"ios";
    NSString *bobyStr = [NSString stringWithFormat:@"username=%@&password=%@", username, pwd];

    // 2.2.1 跟服务器的交互,全部传递的二进制
    request.HTTPBody = [bobyStr dataUsingEncoding:NSUTF8StringEncoding];

    // step_3:建立连接接受返回数据
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {

        // 反序列化
        id result = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];

        NSLog(@"%@", result);
    }];

}

结果:可以看到与浏览器返回的数据是一致的。

2016-03-15 15:58:28.645 NetOperation[1633:120687] {
    userId = 1;
    userName = xufeng;
}

总结:与GET不同的是

    1)使用NSMutableURLRequest类来申明请求,因为后续需要设置此request。

    2)需要显式的设定reguest为POST

    3)参数不会拼接到URL而是使用以二进制数据的形式设定到request的请求体中。

4.网络高级操作--文件上传

前提:保证服务器端目标文件夹为可读写。

与之前过程一样,我们先进行浏览器的操作然后在使用代码来模拟实现。

打开http://127.0.0.1/post/upload.html

                

选择文件上传并观察网络请求:

我们可以看到文件已经被成功上传到服务器:

                          

对应的请求行和请求行如下:             

POST /post/upload.php HTTP/1.1
Host: 127.0.0.1
Connection: keep-alive
Content-Length: 221558
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Origin: http://127.0.0.1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.80 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryOKUHB11qxaAPiisz
Referer: http://127.0.0.1/post/upload.html
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.8

请求体:

我们现在了解了上传是基于POST方式,按照之前的操作我们需要在代码中来模拟实现。

而在操作步骤中唯一不同的就是对于request的包装,所以上传文件部分给NSMutableURLRequest增加一个分类来生成请求。

代码实现:

#import "NSMutableURLRequest+Multipart.h"

/**随便的字符串作为分隔符*/
static NSString *boundary = @"xufeng-test";

@implementation NSMutableURLRequest (Multipart)

+ (instancetype)requestWithURL:(NSURL *)url andLoaclFilePath:(NSString *)loaclFilePath andFileName:(NSString *)fileName
{

    //step_2:创建request
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:1 timeoutInterval:2.0f];
    // 2.1 指定post方法
    request.HTTPMethod = @"POST";

    // 2.2 拼接数据体
    NSMutableData *dataM = [NSMutableData data];
    NSString *str = [NSString stringWithFormat:@"\r\n--%@\r\n", boundary];
    [dataM appendData:[str dataUsingEncoding:NSUTF8StringEncoding]];

    str = [NSString stringWithFormat:@"Content-Disposition: form-data; name=\"userfile\"; filename=\"%@\" \r\n", fileName];
    [dataM appendData:[str dataUsingEncoding:NSUTF8StringEncoding]];

    // 这里直接指定为octet-stream,这样可以针对全部的文件格式
    str = @"Content-Type: application/octet-stream\r\n\r\n";
    [dataM appendData:[str dataUsingEncoding:NSUTF8StringEncoding]];

    // 要上传图片的二进制
    [dataM appendData:[NSData dataWithContentsOfFile:loaclFilePath]];

    str = [NSString stringWithFormat:@"\r\n--%@--\r\n", boundary];
    [dataM appendData:[str dataUsingEncoding:NSUTF8StringEncoding]];

    // 2.3 设置请求体
    request.HTTPBody = dataM;

    // 2.4 设置请求头
    NSString *headerStr = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
    [request setValue:headerStr forHTTPHeaderField:@"Content-Type"];

    return request;
}

调用:

- (void)postUpLoadFile {

    // 1. 创建URL
    NSURL *url = [NSURL URLWithString:@"http://127.0.0.1/post/upload.php"];

    // 2. 创建request
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url andLoaclFilePath:[[NSBundle mainBundle] pathForResource:@"test.png" ofType:nil] andFileName:@"test.png"];

    // 3. 建立连接接受返回数据
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {

        // 4. 反序列化数据
        id result = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];

        NSLog(@"result = %@", result);
    }];
}

结果:

2016-03-15 17:15:38.472 NetOperation[1878:154238] result = {
    userfile =     {
        error = 0;
        name = "test.png";
        size = 221340;
        "tmp_name" = "/private/var/tmp/phpUWTlJ2";
        type = "application/octet-stream";
    };
}

查看服务器文件夹,已经正确上传:

完毕。

时间: 2024-08-24 03:40:58

[New learn] 网络基础-网络操作的相关文章

网络基础——网络协议

一.操作系统基础 操作系统:(Operating System,简称OS)是管理和控制计算机硬件与软件资源的计算机程序,是直接运行在"裸机"上的最基本的系统软件,任何其他软件都必须在操作系统的支持下才能运行. 注:计算机(硬件)->os->应用软件 回到顶部 二.网络通信原理 回到顶部 2.1 互联网的本质就是一系列的网络协议 一台硬设有了操作系统,然后装上软件你就可以正常使用了,然而你也只能自己使用 像这样,每个人都拥有一台自己的机器,然而彼此孤立 如何能大家一起玩耍 然

网络基础-网络OSI七层模型概述

一.为什么学习 网络与我们的生活息息相关,能上网的地方都离不开网络的支持,整体听小伙伴们谈论网络相关的知识,自己却无从插口... 工作中发邮件.聊扣扣生活中玩网游等,我们通过网络所做的事情都与网络低层有关.终归到底,自己还是一个做编程的,这些都不懂,学习中处处遇障碍,所以要学习这块. 二.分层的概念 分层在生活中随处可见,公司分老板.总监.经理.小团队,传销团伙也是金字塔形的,只要是个组织,都会有分层的概念.一般来说:低层是为高层服务的,每一层都可以使用下层提供的服务,并向高层提供服务. 三.O

Python服务器开发二:Python网络基础

Python服务器开发二:Python网络基础 网络由下往上分为物理层.数据链路层.网络层.传输层.会话层.表示层和应用层. HTTP是高层协议,而TCP/IP是个协议集,包过许多的子协议.包括:传输层的 FTP,UDP,TCP协议等,网络层的ip协议等,高层协议如HTTP,telnet协议等,HTTP是TCP/IP的一个子协议. socket是对TCP/IP协议的封装和应用(程序员层面上).也可以说,TPC/IP协议是传输层协议,主要解决数据如何在网络中传输,而HTTP是应用层协议,主要解决如

Python服务器开发 -- 网络基础

Python服务器开发 -- 网络基础 网络由下往上分为物理层.数据链路层.网络层.传输层.会话层.表示层和应用层.HTTP是高层协议,而TCP/IP是个协议集,包过许多的子协议.... 网络由下往上分为物理层.数据链路层.网络层.传输层.会话层.表示层和应用层. HTTP是高层协议,而TCP/IP是个协议集,包过许多的子协议.包括:传输层的 FTP,UDP,TCP协议等,网络层的ip协议等,高层协议如HTTP,telnet协议等,HTTP是TCP/IP的一个子协议. socket是对TCP/I

linux入门基础——网络基础

linux网络基础 网络原理 网络编址 IP编址 IP编址是一个双层编址方案,一个IP地址标识一个主机(或者一个网卡接口) 现在应用最为广泛的Ipv4编址,已经开始逐渐向Ipv6编址切换 Ipv4地址为32位长,Ipv6地址为128位长 一个Ipv4地址分为两个部分:网络部分和主机部分 网络部分用来标识所属区域.主机部分用来标识该区域中的哪个主机 IP地址 Ipv4地址分为32位长度,通常使用点分十进制方式表示 整个IP地址分为4个部分,每个部分8位 例如: 192.168.1.1 110000

python 网络篇(网络编程)

一.楔子 你现在已经学会了写python代码,假如你写了两个python文件a.py和b.py,分别去运行,你就会发现,这两个python的文件分别运行的很好.但是如果这两个程序之间想要传递一个数据,你要怎么做呢? 这个问题以你现在的知识就可以解决了,我们可以创建一个文件,把a.py想要传递的内容写到文件中,然后b.py从这个文件中读取内容就可以了. 但是当你的a.py和b.py分别在不同电脑上的时候,你要怎么办呢? 类似的机制有计算机网盘,qq等等.我们可以在我们的电脑上和别人聊天,可以在自己

Docker 学习笔记【2】 Docker 基础操作实,Docker仓库、数据卷,网络基础学习

Docker 学习笔记[3] Docker 仓库实操,创建私有仓库,实操数据卷.数据卷容器,实操 网络基础  ---------高级网络配置和部分实战案例学习 ============================================================= Docker 学习笔记[1]Docker 相关概念,基本操作--------实操记录开始 ============================================================= 被

网络基础篇----计算机网络基本概述(1)

享受生活  热爱挑战                                                                刘明远分享    一   计算机网络基本概述(1) 每章一段话: 不要让自己闲下来,给自己找些事情做.哪怕是看看书. 正文   (提示:本章内容比较无聊,最好当看故事一样来看,不必记下只需了解,内容基础) 1什么是计算机网络 号称新的"电力火花"是以计算机.通信.信息技术为支撑的计算机网络技术. 计算机网络将两台或多台计算机通过电缆或网络设

谢烟客---------Linux之网络基础知识

本地网络通信 跨网络通信 主机间通信 互联网通信 ISO的OSI模型 网络:是什么,用什么设备 IPV4 IPV6 是什么 ipv4/ipv6首部格式 tcp首部/udp首部 通信的细节.拥塞控制.划动窗口 tcp有限状态机的转换 网络:将多个主机用通信线缆连接起来,实现通信.资源共享 硬盘与主板通信用基于工业标准的线缆和控制器即可完成 网络通信,同轴线缆 1)多个主机共用一个线缆,如何确定谁发和谁收:唯一的标识,IANA国际组织规范 2)硬件生产的规范 局域网: parc (鼠标.LAN,GU