Java基础之网络编程(二)
一、OSI七层网络模型
- Open System Interconnection Reference Model
- 开放式系统互联通信参考模型,OSI模型
- 使各种计算机在世界范围内互连为网络的标准框架
1.1 应用层
- 直接面向用户的程序或者服务,包括系统程序和用户程序。
- www、FTP、DNS、POP3、SMTP等都是应用层服务。
1.2 表现层
- exe不能在linux下安装,shell在windows也不能直接运行。
- 如果linux给windows发数据包,两个系统语法不一致,需要解决这个问题。
- 表现层就解决了不同系统之间的通信语法问题。
- 主要是解释通讯数据的意义,如代码转换、格式变换等,使不同的终端可以表示,还包括加密与解密、压缩与解压缩等。
1.3 会话层(Session)
- 建立和管理应用程序之间的通信。
- 一旦建立连接,会话层的任务就是管理会话。
1.4 传输层
-
当发送大量数据的时候,可能需要很长时间。
-
例如:一个视频几百MB,网络经常会中断几十ms。因此要多发出去的数据进行封装,封装成多个数据小包,一个个进行发送。
1.4.1 TCP协议
- 适用于发送大量数据的准确传输
- 例如发送一万个数据包,另一台计算机就需要告诉我是否接收到一万个数据包,如果缺少一部分包,就会告诉我哪些包丢失了,那我再进行一次发送,这样就能保证对方把这个文件完整接收。
1.4.2 UDP协议
- 适用于发送少量数据,尽量进行交付,不保证可靠交付。
- 例如发送20个数据包,不管你收到多少。在多人网络游戏中,经常使用UDP协议,一般都是简单的信息,而且有一对多的需求。
- 如果用TCP,效率就会很低,因为它会不停地告诉主机收到了多少个数据包,如果有一万台计算机都如此,那么有TCP反而会降低效率,还不如用UDP。
1.5 网路层
- 从源主机到目的主机选择一条合适的传输路径。
- 承接传输层,为端到端的数据传输提供服务。
- 通过路由器,具有寻址功能的设备实现功能。
- IP协议。
- 连接到Internet的每一个主机(计算机或路由器)至少有一个IP地址。
1.6 数据链路层
- 定义了如何让格式化数据进行传输,以及如何让控制对物理介质的访问。
- 这一层通常还提供错误检测、纠正、流量控制,以确保数据的可靠传输。
1.7 物理层
- 两个硬件之间如何进行通信,具体就是一台发bit流,另一条能够收到。
- 定义了设备标准,如网线的接口类型、管线的接口类型、各种传输介质的传输速率等。
- 发送端把1/0转化为电流,到达目的之后再转化为1/0,也就是我们常说的数模转换。
小结
- 数据在发送时是数据从应用层到物理层的一个打包的过程,接收时是数据从物理层到应用层的一个解包过程。
- 从功能角度可以分为三组:567层处理对应用进程的访问,34层解决传输问题,12层解决网络通信问题。
- 从控制角度可以分为二组:4567是主机控制层,123层是通信子网。
二、TCP/IP四层网络模型
-
由于OSI七层体系结构太复杂,在实际应用中TCP/IP的四层体系结构得到广泛应用。
-
OSI与TCP/IP对比图
-
简化了计算机的网络结构,由原来的七层变成现在的四层,但功能并没有减少。
-
每一层既独立又有联系,一层出现问题不会影响其他层的工作,联系是因为上层协议又使用下层协议提供的服务。
-
每一层通过若干协议完成不同的功能,上层协议使用下层协议提供的服务。
-
数据封装过程:
- 一个数据发出后,到达传输层,在原始数据加上TCP头部,到达网络层加上IP头部信息交给下一层,到达数据链路层后,加上以太网头部后成为一个以太网帧。
- 发送给目标主机,到达目标主机后,每一层根据头部信息选择对应协议,进行解析去掉各自的头部,再交给上一层,最终到达目标主机的应用程序上。
-
小结:
- 分层的架构灵活性好,改变其中任意一层,只要接口保持不变,则其它层不会受到影响。
- 易于实现和维护。
- 促进了标准化的工作,每一层功能有了精确的说明。
三、TPC协议的三次握手
- 总览
- TCP作为一种可靠传输控制协议
- 核心思想:保证数据可靠传输,提高传输效率
- 三次握手建立连接
- 详解每一次握手:
- 第一次握手,客户端发送数据包给服务器端,证明了客户端有发送的能力。
- 第二次握手,服务器端接收到之后,再发送数据包给客户端,证明了服务器端有发送和接收的能力。
- 第三次握手,客户端接收到服务器端的数据包,再发送数据包给服务器端,证明了客户端有接收的能力。
- 所以每一次握手都是去完成相对应的功能,只有确认客户端和服务器端都有发送和接收的能力,才能保证整个TCP连接的可靠性。也证明了TCP协议是全双工的协议。
- 假设两次握手可以建立连接
- 第一次客户端发送请求,第一次握手请求由于网络阻塞等原因卡顿。
- 客户端发送第二次请求,这一次服务端收到了,经过两次握手后建立简介,双方都进入ESTABLISHED状态开始传输数据。
- 传输完成后,释放第二次请求所建立的双方TCP连接,客户端和服务端都进入CLOSED状态。
- 这时候被阻塞的第一次请求重新到达服务端。
- 服务端接收到后,开辟空间准备接收连接,并且发送数据包给客户端。
- 但是这时客户端处于CLOSED状态,它是不会接收服务端发过来的数据包的。
- 服务端发送完之后,由于没有第三次握手,它不知道客户端已经关闭。
- 服务端将会一直等待下去,浪费服务端连接资源。
四、TCP协议的四次挥手
- 为了保证发送和接收的双方能够正确释放已经建立的TCP连接,必须经过四次挥手的过程。
-
详解:
- 第二次挥手后,客户端向服务器的单边连接释放了,但是服务器仍然可以发送数据,客户端依然要接收。
- 第四次挥手后,客户端发送释放报文后,必须经过2*MSL(最长报文寿命)的时间后,客户端才会进入CLOSED状态。
- 服务器结束TCP连接的时间要比客户端早一些。
-
为什么需要等待2*MSL
- 防止第四次挥手发送的消息超市,预留2*MSL的时间可以处理超时,完成重发。
- 防止客户端在服务端确认关闭前,再次连接上该服务端,保证该连接关闭的顺序正确。
4.1 TIME_WAIT
- 被动关闭放发送FIN报文(第三次挥手),并等待主动关闭方返回ACK报文(第四次挥手)。
- 若最终ACK丢失(第四次挥手失败),被动关闭方将重新发送FIN报文(第三次挥手),主动关闭方必须维护状态信息TIME_WAIT,保证自己可以接收,然后再重发最终的ACK报文。
- 缺点:
- 主动断开方处于TIME_WAIT状态时,源端口无法使用。
- 端口最大数是65535,因此如果频繁主动断开TCP连接,将很快耗尽端口号。一旦达到了上限,则新的请求就无法处理,接着就是大量Too Many Open Files异常,然后tomcat、nginx、apache崩溃。
- 解决办法:
- 解决TIME_WAIT大量出现,核心思想就是打开系统的TIME_WAIT重用和快速回收。
- net.ipv4.tcp_tw_recycle=1表示开启TCP连接中TIME_WAIT sockets的快速回收,默认为0,表示关闭。
- net.ipv4.tcp_tw_reuse=1表示开启重用,允许将TIME_WAIT sockets重新用于新的TCP连接,默认为0,表示关闭。
4.2 CLOSE_WAIT
-
在对方关闭连接后,自身程序里没有检测,或者本身忘了需要关闭连接,于是这个资源就一直被程序占用着。
-
解决办法:
- 关闭正在运行的程序。
- 尽快修改程序中存在的bug,然后测试提交到线上服务器。
五、TCP粘包问题
5.1 TCP连接的概念
- TCP是一种流式连接,它是指TCP的数据传输就像一种水流一样,并不区分不同数据包之间的界限。
- 就像打开水龙头后,水自然流出,并不知道背后的水泵是分了几次将水供上来的。
5.2 TCP连接的发送方式
- 当TCP两端建立连接后,第一次发送100个字节,第二次再发送100个字节。
- 接收端不一定会分两次接收100字节,为了提高效率,发送端经常将多个数据包缓存起来,合成一个数据包进行发送。
5.3 粘包问题
- 简单来说,就是两个不同的数据包,被合并成一个数据包,造成错误处理,例如发送一个100字节的数据包给应用程序A使用,同时发送一个100字节的数据包给应用程序B使用,但是这两个100字节的数据包被合并成一个200字节的数据包,系统会认为这200字节的数据包是给一个应用程序使用的,所以造成了错误处理。
- TCP默认使用Nagle算法,主要作用是减少网络中报文段的数量,发送端会将较小的内容拼接成大的内容,一次性发送到服务器端。
- TCP接收数据包时,并不会马上交到应用层进行处理,或者说应用层并不会立即处理。实际上接收到数据包会保存在缓存里,然后应用程序主动从缓存读取数据进行处理。
- 当传输文件这种数据时,流式的传输非常适合,但传输指令类的数据结构时,流式模型就有一个问题:无法知道一个指令的结束点,不知道这些数据是属于一个数据包还是属于多个数据包。
5.4 解决方法(短连接)
- 需要发送数据的时候建立TCP连接,发送完一个数据包后就断开TCP连接,这样接收端自然就知道数据结束了。
- 多次建立TCP连接,性能低下。
5.5 解决方法(长连接)
- 接收端如果知道如何对数据包进行分割,便可以解决粘包问题。
- 发送端可以在发送数据之前,向接收端告知发送内容的大小。
- 所以对于处理粘包的关键在于提前获取到数据包的长度,无论这个长度是提前商定好的还是写在数据包的开头的。
5.6 长连接问题(一)
- 选一个固定字符串作为数据包的结束标志,发现这个字符就代表一个数据包传输完成。
- 但在一些情况下很难确定该字符到底是结束标志,还是属于原本要传输的数据内容。
- 实现比较复杂、低效。
5.7 长连接问题(二)
- 在每次发送数据的固定偏移位置,写入数据包的长度。
- 接收端只要一开始读取固定偏移的数据,可以知道这个数据包的长度。
- 当收到的数据长度不足时,就继续接收直到满足长度为止。
- 当收到的数据多余固定长度时,需要截断数据,并将多余的数据缓存起来,视为长度不足需要再次接收处理。
六、HTTP协议
6.1 HTTP协议简介
- HTTP是互联网上应用最为广泛的一种网络协议,超文本传输协议。所有的WWW文件都必须遵守这个标准。
- 设计最初目的:一种发布和接收HTML页面的方法,用于从服务器传输超文本到本地浏览器的传输协议。
6.2 HTTP协议组成
- HTTP协议由HTTP请求和HTTP响应组成。
- 当在浏览器中输入网址访问网站时,浏览器会将请求封装成一个HTTP请求,发送给服务器站点。服务器接收到请求后,会组织响应数据封装成一个HTTP响应返回给浏览器,没有请求就没用响应。
6.3 HTTP协议使用:
- HTTP协议的使用一般基于TCP协议。
- HTTP协议处于OSI七层协议中的应用层,TCP解决的是传输层的逻辑,提供传输控制,按顺序组织数据,和错误纠正。
- HTTP协议的瓶颈及其优化技巧都是基于TCP协议本身的特性。
6.4 HTTP 1.0
- HTTP 1.0规定浏览器与服务器只保持短暂的连接。
- 浏览器的每次请求都需要与服务器建立一个TCP连接,服务器完成请求后立即断开TCP连接,服务器不跟踪每个客户也不记录过去的请求。
- 早起的网页基本只有大段的问题,用1.0 没有问题。但是现在的网页打开之后,需要加载大量的图片、css、js等,需要发送多次请求。
6.5 HTTP 1.1
- 在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟。
- 允许客户端不用等待上一次请求结果返回,就可以发出下一次请求。但服务器端必须按照接收到客户端的先后顺序,依次回送响应结果,以保证客户端能够区分出每次请求的响应内容。
- 这意味着,先接收到的请求的响应也要先发送。这样造成的问题是,如果最先收到的请求的处理时间长的话,响应生成也慢,就会阻塞已经生成了的响应的发送,造成队首阻塞。
6.6 HTTP 2.0
- 最关键的是支持了多路复用,HTTP 1.1如果客户端向发送多个并行的请求,那么必须使用多个TCP连接。
- HTTP 2.0中,采用二进制分帧机制,帧是最小的数据单位(HTTP 1.1中最小数据单位是数据报文),客户端和服务器把HTTP消息分解为互不依赖的帧,然后乱序发送,然后再接收端重新组装,这样就完成了消息的传输。
- 在一个TCP连接中存在多个流,可以同时发送多个请求。
- 在发送端这些帧乱序发送,在接收端并行交错地发送响应,响应之间互不干扰。通过该技术,避免了HTTP 1.1的队首阻塞问题,极大提高传输性能。
七、HTTPS协议
7.1 HTTPS协议的出现
- HTTP协议在传输过程中,数据都是未加密的明文,非常不安全。
- 为了保证这些隐私数据能加密传输,SSL/TLS协议出现,用于对HTTP协议传输的数据进行加密处理。
7.2 HTTPS协议的概念
- 使用HTTPS协议在传输数据之前,需要客户端(浏览器)与服务端(网站)之间进行一次握手,在握手过程中将确立双方传输数据的时候使用的密码。
- TLS/SSL协议不仅仅是一套加密传输的协议,TLS/SSL中使用了非对称加密,对称加密以及HASH算法。
7.3 加密算法
- 对称加密:加密和解密使用同一个密钥
- 非对称加密:一个公开发布的公钥用于加密,另一个由用户自己秘密保存的私钥用于解密。公钥机制灵活,但加密和加密速度却比对称密钥加密慢得多。
- 解释:
- 浏览器与网站互相发送加密的握手消息并验证,目的就是为了保证双方都获得了一致的密码,然后利用这个密码来完成后续数据的加密和解密。
- 其中非对称加密算法用于在握手过程中加密生成的密码,对称加密算法用于对真正传输的数据进行加密,而HASH算法用于验证数据的完整性。
- 由于浏览器生成的密码是整个数据加密的关键,因此在传输的时候使用了非对称加密算法对其加密。
八、打开一个网址的整个过程
8.1 DNS解析
- 打开浏览器,请求csdn.net
- 查找DNS服务器,通过DNS服务器解析域名后,返回对应的IP地址47.95.164.122.
8.2 应用层
- 将浏览器发出的请求,遵循HTTP协议,包装成一个HTTP请求数据包。
8.3 传输层
- 传输层配合应用层的HTTP协议,使用TCP协议建立可靠连接。
- TCP连接需要设置端口,发送方的端口随机选一个,接收方的端口一般是默认80端口。
- 对HTTP请求数据包进行封装,加上TCP头部信息,存放端口号信息。
8.4 网络层
- 通过IP协议,对TCP数据包进行封装,再加上一个IP头,包含本机和目标机器的IP地址。
8.5 数据链路层
- 要保证确实能传到接收方,还需要接收方的MAC地址,也就是物理地址。
- IP地址和MAC地址是对应的关系,一个网络设备的IP地址可以更换,但是MAC地址一般是固定不变的。
- 通过ARP协议可以将IP地址解析成对应的MAC地址。
- 通过以太网协议,会把IP头和IP数据包封装到以太网数据包里去,然后再加一个以太网数据包的头,头里放了本机网卡MAC地址,和网关的MAC地址,形成一个以太网帧。