网络01

作者: xwf_code | 来源:发表于2016-10-29 10:12 被阅读0次

    1.为什么学习网络?

    1.1 学习网络是学习实时更新数据的手段
    1.2 掌握了实时更新数据的手段,可以使APP变得更加有吸引力
    1.3 数据的实时的更新是在服务器端发生的
    1.4 客户端只需要把服务器最新的数据加载到客户端,然后展示即可
    1.5 客户端的网络开发只做一件事,向服务器发送网络请求,得到服务器的"最新"数据展示在界面上
    1.6 客户端的开发者,只需要关心"请求怎么发,响应怎么处理"

    2.网络核心

    2.1 客户端 : 就是手机 / APP
    2.2 服务器端 : 为客户端提供数据的"特殊"的计算机
    2.3 请求 : 客户端向服务器端获取数据的行为
    2.4 响应 : 服务器端对客户端的请求作出的反应

    3.网络开发的结构

    3.1 客户端 : 发送请求,告诉服务器自己要什么数据
    3.2 服务器端 : 服务器得到客户端的请求之后,就去数据库里面找客户端需要的数据,如果找到就把数据发送客户端
    3.3 数据库 : 专门存放数据的地方
    3.4 实际开发中,作为移动端开发,只需要关心客户端的开发就可以了

    4.服务器

    4.1 测试服务器 : 在开发阶段使用的服务器,是本地的,所以数据加载比较快,方便前后端开发者调节数据
    4.2 正式服务器 : APP发布上线之后,访问的服务器;里面的数据都是正确的,可以被任何备用户访问
    4.3 黑马学习网络课程,选择的是本地apache服务器,只在学习时使用;实际开发,使用自己公司的测试和正式服务器

    5.URL

    http://open.api.yaolan.com/api/bbs/post?limit=20&start=0&source=ios&tid=53251140&token=3784

    5.1 URL的概念 : 统一资源定位符 (数据在网络中的路径 / 地址)

    5.1.1 通过唯一的URL可以获取到网络中唯一的数据
    5.1.2 每个人都有住址.URL就是类似人的住址.

    5.2 URL的格式

    5.2.1 协议头
    http:// 表示传输任何数据
    https:// 表示传输任何安全数据
    ftp:// 表示传输大文件
    tel:// 表示打电话的 (tel://18510000001)
    sms:// 表示发送短信 (sms://18510000001)
    mailto:// 表示发送邮件 (mailto://zhangjiesharp@163.com)

    5.2.2 服务器地址 / 域名 / 服务器IP
    "open.api.yaolan.com" : 表示向哪个公司的服务器获取数据
    "www.baidu.com" : 表示向百度公司的服务器获取数据
    服务器地址 服务器地址 / 域名 / 服务器IP : 表示这个计算机在互联网中的地址 / 位置的标识
    "14.215.177.38" : 表示百度服务器在互联网中的IP地址
    "www.baidu.com" : "14.215.177.38" 是一一对应的
    提示 : 域名比四分十进制的IP表示法,更加好记忆
    为什么通过域名就可以访问到百度的服务器? DNS服务器(域名解析服务器)会把域名解析成IP地址

    5.2.3 数据存放的路径
    数据存放在数据库中的,数据库是个硬件设备,类似电脑的磁盘;
    类似于 : 磁盘里面存放数据是需要指定路径的

    5.2.4 URL的参数
    参数就是告诉服务器我要什么样的数据,比如,要几条数据...

    6.HTTP协议

    6.1 协议
    6.1.1 协议概念 : 规定了请求和响应的格式;还规定了URL的格式;还规定了请求怎么发,响应怎么发;
    6.1.2 协议作用 : 一旦规定好了请求和响应的格式之后,那么服务器就可以读懂客户端的请求;而且客户端也可以读懂服务器的响应

    6.2 HTTP协议 : 超文本传输协议;
    6.2.1 超文本 : 表示任何数据
    6.2.2 超文本传输协议 : 表示可以传输任何数据
    6.2.3 比较 : tel:// 只能打电话,不能传输超文本数据

    7.HTTP协议特点

    7.1 简单 / 快速 / 灵活
    7.2 HTTP协议版本
    7.2.1 提示 : HTTP协议版本的选择不是客户端的事情,是服务决定的.不要瞎操心;
    7.2.1 HTTP协议版本分为
    HTTP 0.9 和 HTTP 1.0 "使用非持续链接"

    1."非持续链接" : 一次链接只能处理一次请求和响应
    2.两个计算机之间要想能够传输数据,必须先建立好链接
    3.非持续链接,一旦发送一个请求,处理一个响应,链接就"立即断开"
    4.下次如果还要发送请求,需要再次建立链接
    5.使用场景 : 对服务器资源占用要求高的APP
    6.好处 : 可以及时释放服务器的链接压力
    7.缺点 : 每次请求和响应之前都要建立链接,消耗资源

    HTTP 1.1 "使用持续链接"

    1."持续链接" : 一次链接可以处理多次请求和响应
    2.两个计算机之间要想能够传输数据,必须先建立好链接
    3.当一次请求和响应结束之后,那么这个"链接会持续一段时间"
    4.在链接持续的时间内,可以发送多次请求和响应
    5."持续链接迟早还是会断开的"
    6.使用场景 : 对服务器资源占用要求高的APP
    7.好处 : 可以及时释放服务器的链接压力
    8.缺点 : 每次请求和响应之前都要建立链接,消耗资源

    8.短连接和长连接和心跳包
    8.1 短连接 : 包含非持续链接和持续链接
    8.1.1 总之会断开
    8.1.2 能够及时释放服务器资源
    8.1.3 让服务器能够为更多的用户提供服务

    8.2 长连接
    8.2.1 一旦建立链接就不会"主动断开";除非退出登录,程序闪退,断网...才会断开链接
    8.2.2 不能及时释放服务器资源;那么就会对服务器的性能要求很高,要去服务器具备高并发性(能够链接更多的用户)
    8.2.3 使用场景 : 需要数据及时到达的APP(及时通讯 : 微信,扣扣,陌陌...)

    8.3 心跳包
    8.3.1 是"检测长连接"的重要手段
    8.3.2 心跳包的发起者可以是客户端,可以是服务器

    9.请求和响应

    9.1 请求
    请求行 : "GET / HTTP/1.1" 请求方法 空格 资源路径 空格 协议版本
    请求头 : 客户端告诉服务器一些额外信息,其中包括服务器地址(host : 必不可少)/设备环境...
    请求体(可选) : GET请求是没有请求体,只有POST请求有请求体

    9.2 响应
    状态行(响应行) : "HTTP/1.1 200 OK" 协议版本 空格 状态码 状态码英文描述
    响应头 : 服务器告诉客户端的额外信息,其中包括服务器端的版本,服务器类型,文件在服务器大小,文件在服务器类型...
    响应体 : 客户端发送请求的目的;就是保存在服务器数据库里面的数据

    10.NSURLConnection的使用

    10.1 创建URL
    10.2 创建请求 (NSURLRequest / NSMutableURLRequest)
    10.3 异步发送请求,异步获取数据
    10.4 "如果获取到服务器发送过来的响应体(data : 二进制) : 需要把二进制反序列化,转成客户端可以直接使用的OC对象"
    10.5 把反序列化之后的数据展示到控件上

    11.网络通信三要素
    11.1 通过IP找服务器,通过端口号找处理请求的进程,通过传输协议确定数据如何传输

    12.UDP和TCP传输协议

    12.1 UDP(数据报文协议)
    12.1.1 相当于广播,数据在传输之前你不需要先建立链接
    12.1.2 非安全的传输协议,容易丢包
    12.1.3 流媒体,视频的实时共享

    12.2 TCP(数据控制协议)
    12.2.1 相当于打电话,数据在传输之前,计算机之间一定要先建立好链接
    12.2.2 安全的传输协议,不容易丢包
    12.2.3 使用场景,适用绝大多数APP
    12.2.4 只要你的协议是HTTP / HTTPS协议,就表示你选择的传输协议就是TCP

    13.Socket开发体验

    13.1 如果客户端使用Socket进行网络开发,需要做那几件事情?
    创建客户端Socket
    客户端Socket链接到服务器端Socket
    客户端Socket向服务器Socket发送请求
    客户端Socket接收服务器Socket发送的响应
    关闭客户端Socket

    - (void)viewDidLoad {
        [super viewDidLoad];
        
        // 1.创建客户端Socket
        /**
         参数
         参数1 : domain,协议域/协议簇,AF_INET(IPV4的网络开发)
         参数2 : type,Socket类型,SOCK_STREAM(TCP)/SOCK_DGRAM(UDP,报文)
         参数3 : protocol,IPPROTO_TCP,协议,如果输入0,可以根据第二个参数,自动选择协议
         提示 : SOCK_STREAM 表示请求是HTTP请求
         
         返回值
         int类型,如果 > 0 就表示成功,返回socket
         clientSocket : 就是套接字描述符
         */
        int clientSocket = socket(AF_INET, SOCK_STREAM, 0);
        if (clientSocket > 0) {
            NSLog(@"创建客户端Socket成功");
        }
        
        // 2.客户端Socket连接到服务器Socket
        /**
         参数
         参数1 :  客户端socket / 套接字描述符
         参数2 :  指向数据结构sockaddr的指针,其中包括目的端口和IP地址
         参数3 :  结构体数据长度
         
         返回值 : int类型,返回0表示成功;反之,失败;
         */
        // 创建指向sockaddr_in的指针;这个结构体里面封装了端口号和IP
        struct sockaddr_in addr;
        // 设置协议域
        addr.sin_family = AF_INET;
        // 设置端口号
        addr.sin_port=htons(80);
        // 指定目标计算机的IP
        addr.sin_addr.s_addr = inet_addr("14.215.177.37");
        
        int isConnected = connect(clientSocket, (const struct sockaddr *)&addr, sizeof(addr));
        if (isConnected == 0) {
            NSLog(@"客户端Socket链接到服务器Socket成功");
        }
        
        // 3.客户端Socket向服务器Socket发送请求
        /**
         参数
         参数1 : 客户端socket
         参数2 : 发送内容地址 void * == id
         参数3 : 发送内容长度
         参数4 : 发送方式标志,一般为0
         
         返回值
         如果成功,则返回发送的字节数,失败则返回SOCKET_ERROR
         */
        
        // 请求的内容 : 必须严格按照HTTP协议的规定去写
        NSString *sendMsg = @"GET / HTTP/1.1\r\n"
                            "Host: www.baidu.com\r\n"
                            "User-Agent: iphone\r\n"
                            "Connection: close\r\n\r\n"
                            ;
        
        // Socket把请求信息,发送给服务器
        ssize_t sendLen = send(clientSocket, sendMsg.UTF8String, strlen(sendMsg.UTF8String), 0);
        NSLog(@"%ld",sendLen);
        
        // 4.客户端Socket接收服务器Socket发送的响应
        /**
         参数
         参数1 : 客户端socket
         参数2 : 接收内容的容器的地址
         参数3 : 接收内容缓存区长度
         参数4 : 接收方式,0表示阻塞,必须等待服务器返回数据,才执行这个函数,服务器发一次数据,就执行一次
         
         返回值
         如果成功,则返回接收的字节数,失败则返回SOCKET_ERROR
         */
        
        // 定义字符暂存区 : 定义一个专门接收字符的数组,数组名就是数组的地址
        u_int8_t buffer[1024];
        // 先定义非0,保证第一次可以进入循环,一定要是负数,因为服务器给你发送的字节数是正式
        ssize_t recvLen = -1;
        
        // 定义可变data,拼接buffer
        NSMutableData *dataM = [NSMutableData data];
        
        while (recvLen) {
            // recv 默认只接收一次,如果需要把完整的数据接收完,就需要在循环里面接收
            recvLen = recv(clientSocket, buffer, sizeof(buffer), 0);
            NSLog(@"%ld",recvLen);
            
            // 循环拼接buffer
            [dataM appendBytes:buffer length:recvLen];
        }
        
        // 字符串的反序列化
        NSString *html = [[NSString alloc] initWithData:dataM encoding:NSUTF8StringEncoding];
        NSLog(@"%@",html);
        
        // 5.关闭客户端Socket
        close(clientSocket);
    }
    

    相关文章

      网友评论

          本文标题:网络01

          本文链接:https://www.haomeiwen.com/subject/tuxyuttx.html