iOS 整理-网络篇

2020-02-26  本文已影响0人  凉秋落尘

1、网络七层协议
2、Http 和 Https 的区别?Https为什么更加安全?
3、Https的连接建立过程
4、三次握手 和 四次挥手
5、TCP 和 UDP的优缺点
6、Cookie和Session的区别
7、Socket的原理和连接过程
8、iOS Socket封包、粘包、拆包处理

网络七层协议
Http 和 Https 的区别?Https为什么更加安全?

1、HTTPS 需要向机构申请 CA 证书
2、HTTP 属于明文传输,HTTPS基于 SSL(安全套接层) 进行加密传输
3、HTTP 端口号为 80,HTTPS 端口号为 443 。
4、HTTPS 是加密传输,有身份验证的环节,更加安全。

HTTPS的连接建立过程

HTTPS的连接过程通过对称和非对称秘钥进行加密和解密的过程,服务器通过公钥和私钥进行非对称加密,客户端生成随机数进行对称加密。

1、客户端将随机数、安全协议版本号、加密算法表发送给服务器
2、服务器与自己的加密算法表对比,不匹配。如果匹配,服务器发送,对称算法,公钥算法,MAC算法同时还会把数字证书和生成随机数发送给客户端。
3、客户端验证服务器公钥合法性,如果合法则将服务器的公钥来生成一个前主秘钥,将前主秘钥,和两个随机数生成会话秘钥。并通过服务端的公钥来对前主秘钥进行非对称加密,发送给服务端
4、服务端接收到加密信息后,用私钥解密得到主秘钥。并通过前主秘钥和两个随机数来组装会话秘钥。
5、得到两个秘钥后,开始进行数据传输。客户端收到服务器发送来的密文,用客户端密钥对其进行对称解密,得到服务器发送的数据。同理,服务端收到客户端发送来的密文,用服务端密钥对其进行对称解密,得到客户端发送的数据。

三次握手 和 四次挥手
TCP 和 UDP的优缺点
Cookie和Session的区别
Socket的原理和连接过程

Socket(套接字)网络上两个程序通过一个双向通信连接实现数据交互,这种双向通信的连接。Socket可以支持不同的传输协议(TCP或UDP)。
是支持TCP/IP协议的网络通信的基本操作单元,包含进行网络通信的必须的五种信息:连接使用的协议、本地主机的IP地址、本地进程的协议端口、远程主机的IP地址、远程进程的协议端口。

Socket连接过程:
1、客户端调用socket,绑定服务器的ip和端口号,发送一个SYN报文,进入阻塞等待。
2、服务器使用socket,监听状态,等待客户端的连接请求并阻塞当前进程。
3、服务器收到报文,发送ACK确认。
4、客户端收到确认双方开始进行数据传输。(TCP,UDP)
5、通讯结束后关闭socket,关闭连接状态

iOS Socket封包、粘包、拆包处理

我们在使用Socket时,理论上可以正常通信,但是因为防火墙,传输速度,网络等原因,数据传输过程中会可能出现,socket连接中断,丢包,粘包等情况的方式。因此,发送socket的过程就是封包,拆包,处理粘包问题。

socket的报文格式:服务号(4bytes)+长度(4bytes)+数据

我们在转化为二进制数据传输的协议需要依照这样的格式进行传输。报头4个字节长度的空间,用来存储服务号转换成的二进制数据;然后4个字节则是表示数据的总长度的二进制;最后是要传输的数据二进制格式。

在IOS中,同样的发送数据需要将同样的数据转化为二进制,发送出去。例如使用CocoaAsyncSocket进行发送socket时:

    NSString * strJson  = [[NSString alloc] initWithData :data encoding :NSUTF8StringEncoding];
    Cs_Connect *connect = [Cs_Connect new];
    connect.serverID    = 1;
    connect.message     = strJson;
    connect.length      = (int)connect.message.length;

    //将数据传换成二进制数据,怎么转化网上有
    NSMutableData *dataModel =  [socket RequestSpliceAttribute:connect];
    // 通过Socket发出去
    [socket sendMessage:dataModel];

当使用TCP进行传输时,基于TCP的socket是以字节流的方式进行传输。代表这报文块和块之间没有报文边界。
当我们在进行两个或以上的数据一起进行TCP传输时,理想上是一块一块的接收。但是现实往往有偏差,导致数据会出现多种情况:



1、数据D1,D2分开独立到达;
2、数据D1,D2合成一个整体一起到达;
3、数据D1一部分先达到,还有一部分和D2一起到达;
4、数据D1和部分D2先到达,剩下一部分D2单独到达;

除了第一种理想的情况,其他情况会出现数据不完整问题。

为了解决粘包问题,我们需要在拆包的时候进行粘包问题处理。
1、获取报头的长度字段,得到数据的长度和报文D1的总长度。
2、将数据添加并保存在缓存中。
3、根据返回来并保存在数据中的长度和长度截取完整包并返回。
4、删除保存在缓存并已经正常返回的数据包,再读取下一个。

    //将数据存入缓存区
    [self.readBuf appendData:data];
    
    //数据中前面有4个字节的头信息,其中前两位是固定的头长度(用处不大),后两位才是数据的长度。
    //如果大于4个字节证明有消息,因为服务器只要发送数据,必定包含头
    while (self.readBuf.length > 4) {
        
        //将消息转化成byte,计算总长度 = 数据的内容长度 + 前面4个字节的头长度
        Byte *bytes = (Byte *)[self.readBuf bytes];
        NSUInteger allLength = (bytes[2]<<8) + bytes[3] +4;
        
        //缓存区的长度大于总长度,证明有完整的数据包在缓存区,然后进行处理
        if (self.readBuf.length >= allLength) {
            NSMutableData *msgData = [[self.readBuf subdataWithRange:NSMakeRange(0, allLength)] mutableCopy];
            //提取出前面4个字节的头内容,之所以提取出来,是因为在处理数据问题的时候,比如data转json的时候,头内容里面包含非法字符,会导致转化出来的json内容为空,所以要先去掉再处理数据问题
            [msgData replaceBytesInRange:NSMakeRange(0, 4) withBytes:NULL length:0];
    
            NSLog(@"开始处理数据问题");

            //处理完数据后将处理过的数据移出缓存区
            _readBuf = [NSMutableData dataWithData:[_readBuf subdataWithRange:NSMakeRange(allLength, _readBuf.length - allLength)]];
        }else{
            //缓存区内数据包不是完整的,再次从服务器获取数据,中断while循环
            [self.clientSocket readDataWithTimeout:-1 tag:0];
            break;
        }
    }
    
    //读取到服务端数据值后,能再次读取
    [self.clientSocket readDataWithTimeout:-1 tag:0];
上一篇下一篇

猜你喜欢

热点阅读