Android网络知识

一次网络请求的流程:
域名解析 -----> TCP的三次握手 -----> 建立TCP连接后发起HTTP请求 -----> 服务器响应HTTP请求 ----->( 解析返回的数据然后对页面进行渲染并呈现给用户) -----> 四次挥手结束连接。通过本片文章的学习,你讲学会:
1.计算机的网络体系结构
2.Http相关以及get请求和post请求
3.TCP的连接建立和断开以及TCP和UDP的区别
4.Socket基本使用

一.计算机的网络体系结构

计算机网络体系结构分为3种:
OSI体系结构:概念清楚 & 理念完整,但复杂 & 不实用
TCP / IP体系结构:含了一系列构成互联网基础的网络协议,是Internet的核心协议 & 被广泛应用于局域网 和 广域网
五层体系结构:融合了OSI 与 TCP / IP的体系结构,目的是为了学习 和计算机原理
3种计算机网络体系结构如图所示:

计算机网络体系结构

五层体系结构各自负责什么呢?
应用层:如http协议,它实际上是定义了如何包装和解析数据,应用层是http协议的话,则会按照协议规定包装数据,如按照请求行、请求头、请求体包装,包装好数据后将数据传至运输层。
运输层:运输层有TCP和UDP两种协议,分别对应可靠的运输和不可靠的运输,如TCP因为要提供可靠的传输,所以内部要解决如何建立连接、如何保证传输是可靠的不丢数据、如何调节流量控制和拥塞控制。关于这一层,我们平常一般都是和Socket打交道,Socket是一组封装的编程调用接口,通过它,我们就能操作TCP、UDP进行连接的建立等。我们平常使用Socket进行连接建立的时候,一般都要指定端口号,所以这一层指定了把数据送到对应的端口号。
网络层:这一层IP协议,以及一些路由选择协议等等,所以这一层的指定了数据要传输到哪个IP地址。中间涉及到一些最优线路,路由选择算法等等。
链路层:负责把IP地址解析为MAC地址,即硬件地址,这样就找到了对应的唯一的机器。
物理层:这一层就是最底层了,提供二进制流传输服务,也就是也就是真正开始通过传输介质(有线、无线)开始进行数据的传输了。

二.Http相关以及get请求和post请求

HTTP基于TCP的应用层协议。
1.http无连接无状态的
无连接:不是说不需要连接,Http协议只是一个应用层协议,最终还是要靠运输层的如TCP协议向上提供的服务进行连接。无连接的含义是http约定了每次连接只处理一个请求,一次请求完成后就断开连接,这样主要是为了缓解服务器的压力,减小连接对服务器资源的占用。
无状态:指每个请求之间都是独立的,对于之前的请求事务没有记忆的能力。所以就出现了像Cookie这种,用来保存一些状态的东西。
2.请求报文和响应报文
请求报文和响应报文的格式如图所示:

请求报文

响应报文

3.HTTPS
我们都知道Https保证了我们数据传输的安全,Https=Http+Ssl,之所以能保证安全主要的原理就是利用了非对称加密算法,平常用的对称加密算法之所以不安全,是因为双方是用统一的密匙进行加密解密的,只要双方任意一方泄漏了密匙,那么其他人就可以利用密匙解密数据。而非对称加密算法之所以能实现安全传输的核心精华就是: 公钥加密的信息只能用私钥解开,私钥加密的信息只能被公钥解开。
HTTP中GET和POST请求的区别:
GET和POST本质上就是TCP链接,并无差别。但是由于HTTP的规定和浏览器/服务器的限制,导致他们在应用过程中体现出一些不同。
1.GET在浏览器回退时是无害的,而POST会再次提交请求。
2.GET请求会被浏览器主动cache,而POST不会,除非手动设置。
3.GET请求只能进行url编码,而POST支持多种编码方式。
4.GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
5.GET请求在URL中传送的参数是有长度限制的,而POST没有。
6.GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。
7.GET参数通过URL传递,POST放在Request body中。

三.TCP和UDP

TCP
TCP面向连接,提供可靠的数据传输,属于传输层通信协议,基于TCP的应用层协议有HTTP、SMTP、FTP、Telnet 和 POP3 。
1.三次握手建立连接如图所示:

三次握手

第一次:发送SNY=1表示此次握手是请求建立连接的,然后seq生成一个客户端的随机数X
第二次:发送SNY=1,ACK=1表示是回复请求建立连接的,然后ack=客户端的seq+1(这样客户端收到后就能确认是之前想要连接的那个服务端),然后把服务端也生成一个代表自己的随机数seq=Y发给客户端。
第三次:ACK=1。 seq=客户端随机数+1,ack=服务端随机数+1(这样服务端就知道是刚刚那个客户端了)
2.连接的建立为什么需要三次:
第一次握手,C端发了个连接请求消息到S端,S端收到后S端就知道自己与C端是可以连接成功的,但是C端此时并不知道S端是否接收到这个消息,所以S端接收到消息后得应答,C端得到S端的回复后,才能确定自己与S端是可以连接上的,这就是第二次握手。C端只有确定了自己能与S端连接上才能开始发数据。所以两次握手肯定是最基本的。假设一下如果没有第三次握手,而是两次握手后我们就认为连接建立,那么会发生什么?
比如一个情况:C端发出去的第一个网络连接请求由于某些原因在网络节点中滞留了,导致延迟,直到连接释放的某个时间点才到达S端,这是一个早已失效的报文,但是此时S端仍然认为这是C端的建立连接请求第一次握手,于是S端回应了C端,第二次握手。如果只有两次握手,那么到这里,连接就建立了,但是此时C端并没有任何数据要发送,而S端就会傻傻的等待着,造成很大的资源浪费。所以需要第三次握手,只有C端再次回应一下,就可以避免这种情况。第三次握手是为了防止已经失效的连接请求报文段突然又传到服务端,因而产生错误
3.四次握手断开连接如图所示:
四次握手断开连接

4.为什么断开比连接多一次
可以看到这里服务端的ACK(回复客户端)和FIN(终止)消息并不是同时发出的,而是先ACK,然后再FIN,这也很好理解,当客户端要求断开连接时,此时服务端可能还有未发送完的数据,所以先ACK,然后等数据发送完再FIN。这样就变成了四次握手了。
UDP
UDP 提供无连接的、尽最大努力的数据传输服务(不保证数据传输的可靠性),提供无连接的、尽最大努力的数据传输服务(不保证数据传输的可靠性),UDP是面向报文的,UDP没有拥塞控制,因此网络出现的拥塞不会使源主机发送速率降低,UDP支持一对一、一对多、多对一、多对多的交互通信,UDP的首部开销小。其数据传输的单位是用户数据报。
TCP和UDP区别:
1.TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接
2.TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保 证可靠交付
3.TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的 UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等)
4.、每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信
5.TCP首部开销20字节;UDP的首部开销小,只有8个字节
6.TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道

四.Socket基本使用

1.Socket是什么
Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。它的位置如下图所示:


image.png

2.socket的基本操作
socket是“open—write/read—close”模式的一种实现,那么socket就提供了这些操作对应的函数接口。
我们通过socket在客户端发送和接收服务端信息:

public class SocketClient {
  public static void main(String args[]) throws Exception {
    // 要连接的服务端IP地址和端口
    String host = "127.0.0.1";
    int port = 55533;
    // 与服务端建立连接
    Socket socket = new Socket(host, port);

    // 发送,建立连接后获得输出流
    OutputStream outputStream = socket.getOutputStream();
    String message = "你好  yiwangzhibujian";
    socket.getOutputStream().write(message.getBytes("UTF-8"));
    //通过shutdownOutput高速服务器已经发送完数据,后续只能接受数据
    socket.shutdownOutput();
    
    //读取
    InputStream inputStream = socket.getInputStream();
    byte[] bytes = new byte[1024];
    int len;
    StringBuilder sb = new StringBuilder();
    while ((len = inputStream.read(bytes)) != -1) {
      //注意指定编码格式,发送方和接收方一定要统一,建议使用UTF-8
      sb.append(new String(bytes, 0, len,"UTF-8"));
    }
    System.out.println("get message from server: " + sb);
    
    inputStream.close();
    outputStream.close();
    socket.close();
  }
}

五.总结

以上就是关于Android网络的相关知识点,如有不足或者错误的地方请在下方指正。我们需要多看更需要多写,只有不断学习,不断进步才能不被淘汰。

你可能感兴趣的:(Android网络知识)