网络协议和网络编程 重难点 参考资料来源于 netty权威指南(高性能的服务端开发) netty实战 Unix网络编程 AIO 鸟哥的linux私房菜 《刘超的趣谈网络协议》 《图解http》
概念 | 基础知识 |
---|---|
定义 | 计算机网络的各层 + 其协议的集合 |
作用 | 定义该计算机网络的所能完成的功能 |
结构介绍 | 计算机网络体系结构分为3种:OSI体系结构、TCP / IP体系结构、五层体系结构,OSI体系结构:概念清楚 & 理念完整,但复杂/不实用;TCP / IP体系结构:含了一系列构成互联网基础的网络协议,是Internet的核心协议 & 被广泛应用于局域网 和 广域网;五层体系结构(课本):融合了OSI 与 TCP / IP的体系结构,目的是为了学习/讲解计算机原理。 |
由于 TCP / IP体系结构较为广泛,故主要讲解
层级 | 主要任务 | 使用协议 | 协议特点 |
---|---|---|---|
应用层 | 任务是通过应用进程间的交互来完成特定网络应用 | 域名系统DNS/HTTP协议/SMTP协议/文件传输FTP/TFTP/虚拟终端Telnet/SSH/动态主机配置协议DHCP | 把应用层交互的数据单元称为报文 |
运输层 | 负责向两台主机进程之间的通信提供通用的数据传输服务 | 主要使用两种协议:TCP/UDP | 传输控制协议TCP(Transmission Control Protocol)–提供面向连接的,可靠的数据传输服务。用户数据协议 UDP(User Datagram Protocol)–提供无连接的,尽最大努力的数据传输服务(不保证数据传输的可靠性)。 |
网络层 | 任务就是选择合适的网间路由和交换结点, 确保数据及时传送 | IP,ICMP,RIP,OSPF,BGP,IGMP | IP 数据报 |
数据链路层 | 通常简称为链路层。两台主机之间的数据传输,提供封装成帧以及错误检测功能 | SLIP,CSLIP,PPP,ARP,RARP,MTU | 数据链路层将网络层交下来的 IP 数据报组装成帧 |
物理层 | 实现相邻计算机节点之间比特流的透明传送,尽可能屏蔽掉具体传输介质和物理设备的差异 | - | 传送的数据单位是比特 |
FTP:定义了文件传输协议,使用21端口,下载文件,上传主页,都要用到FTP服务
Telnet:它是一种用于远程登陆的端口,用户可以以自己的身份远程连接到计算机上 23端口
SMTP:定义了简单邮件传送协议 25号端口
POP3:它是和SMTP对应,POP3用于接收邮件 110端口
HTTP:从Web服务器传输超文本到本地浏览器的传送协议
DNS:用于域名解析服务,将域名地址转换为IP地址。DNS用的是53号端口
SNMP:简单网络管理协议,使用161号端口,是用来管理网络设备的
TFTP(Trival File Transfer Protocal):简单文件传输协议,该协议在熟知端口69上使用UDP服务
1、为了准确无误地把数据送达目标处,TCP协议采用了三次握手策略。
客户端–发送带有 SYN 标志的数据包–一次握手–服务端
服务端–发送带有 SYN/ACK 标志的数据包–二次握手–客户端
客户端–发送带有带有 ACK 标志的数据包–三次握手–服务端
第一次握手 | Client 什么都不能确认;Server 确认了对方发送正常,自己接收正常 |
---|---|
第二次握手 | Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:对方发送正常,自己接收正常 |
第三次握手 | Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:自己发送、接收正常,对方发送、接收正常 |
三次握手的缺陷:
引起SYN Flood 攻击:SYN-Flood攻击是当前网络上最为常见的DDoS攻击,也是最为经典的拒绝服务攻击。通过向网络服务所在端口发送大量的伪造源地址的攻击报文,就可能造成目标服务器中的半开连接队列被占满,从而阻止其他合法用户进行访问.
如何解决:待补充。
3 为什么要传回 SYN
接收端传回发送端所发送的 SYN 是为了告诉发送端,我接收到的信息确实就是你所发送的信号了。SYN 是 TCP/IP 建立连接时使用的握手信号。在客户机和服务器之间建立正常的 TCP 网络连接时,客户机首先发出一个 SYN 消息,服务器使用 SYN-ACK 应答表示接收到了这个消息,最后客户机再以ACK(Acknowledgement[汉译:确认字符 ,在数据通信传输中,接收站发给发送站的一种传输控制字符。它表示确认发来的数据已经接受无误。 ])消息响应。这样在客户机和服务器之间才能建立起可靠的TCP连接,数据才可以在客户机和服务器之间传递。
4、传了 SYN,为啥还要传 ACK
双方通信无误必须是两者互相发送信息都无误。传了 SYN,证明发送方到接收方的通道没有问题,但是接收方到发送方的通道还需要 ACK 信号来进行验证。
断开一个 TCP 连接则需要“四次挥手”:
客户端-发送一个 FIN,用来关闭客户端到服务器的数据传送;
服务器-收到这个 FIN,它发回一 个 ACK,确认序号为收到的序号加1 。和 SYN 一样,一个 FIN 将占用一个序号;
服务器-关闭与客户端的连接,发送一个FIN给客户端;
客户端-发回 ACK 报文确认,并将确认序号设置为收到序号加1;
运输层协议 | 特点 | 使用时机 |
---|---|---|
UDP | UDP 在传送数据之前不需要先建立连接,远地主机在收到 UDP 报文后,不需要给出任何确认。虽然 UDP 不提供可靠交付,但在某些情况下 UDP 确是一种最有效的工作方式(一般用于即时通信) | QQ 语音、 QQ 视频 、直播等等 |
TCP | 提供面向连接的服务。在传送数据之前必须先建立连接,数据传送结束后要释放连接。 TCP 不提供广播或多播服务。由于 TCP 要提供可靠的,面向连接的传输服务(TCP的可靠体现在TCP在传递数据之前,会有三次握手来建立连接,而且在数据传递时,有确认、窗口、重传、拥塞控制机制,在数据传完后,还会断开连接用来节约系统资源),这一难以避免增加了许多开销,如确认,流量控制,计时器以及连接管理等。这不仅使协议数据单元的首部增大很多,还要占用许多处理机资源。 | TCP 一般用于文件传输、发送和接收邮件、远程登录等场景。 |
序号 | 特点 |
---|---|
1 | 应用数据被分割成 TCP 认为最适合发送的数据块。 |
2 | TCP 给发送的每一个包进行编号,接收方对数据包进行排序,把有序数据传送给应用层。 |
3 | 校验和 :TCP 将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP 将丢弃这个报文段和不确认收到此报文段。(CRC校验:课本知识) |
4 | TCP 的接收端会丢弃重复的数据。 |
5 | 流量控制: TCP 连接的每一方都有固定大小的缓冲空间,TCP的接收端只允许发送端发送接收端缓冲区能接纳的数据。当接收方来不及处理发送方的数据,能提示发送方降低发送的速率,防止包丢失。TCP 使用的流量控制协议是可变大小的滑动窗口协议。 (TCP 利用滑动窗口实现流量控制) |
6 | 拥塞控制: 当网络拥塞时,减少数据的发送。 |
7 | ARQ协议: 也是为了实现可靠传输的,它的基本原理就是每发完一个分组就停止发送,等待对方确认。在收到确认后再发下一个分组。 |
8 | 超时重传: 当 TCP 发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。 |
协议 | 原理 | 优缺点 |
---|---|---|
停止等待ARQ协议 | 原理就是每发完一个分组就停止发送,等待对方确认(回复ACK)。如果过了一段时间(超时时间后),还是没有收到 ACK 确认,说明没有发送成功,需要重新发送,直到收到确认后再发下一个分组;在停止等待协议中,若接收方收到重复分组,就丢弃该分组,但同时还要发送确认 | 优点: 简单,缺点: 信道利用率低,等待时间长 |
连续ARQ协议 | 连续 ARQ 协议可提高信道利用率。发送方维持一个发送窗口,凡位于发送窗口内的分组可以连续发送出去,而不需要等待对方确认。接收方一般采用累计确认,对按序到达的最后一个分组发送确认,表明到这个分组为止的所有分组都已经正确收到了。 | 优点: 信道利用率高,容易实现,即使确认丢失,也不必重传。缺点: 不能向发送方反映出接收方已经正确收到的所有分组的信息。 比如:发送方发送了 5条 消息,中间第三条丢失(3号),这时接收方只能对前两个发送确认。发送方无法知道后三个分组的下落,而只好把后三个全部重传一次。这也叫 Go-Back-N(回退 N),表示需要退回来重传已经发送过的 N 个消息。 |
慢开始 | 慢开始算法的思路是当主机开始发送数据时,如果立即把大量数据字节注入到网络,那么可能会引起网络阻塞,因为现在还不知道网络的符合情况。经验表明,较好的方法是先探测一下,即由小到大逐渐增大发送窗口,也就是由小到大逐渐增大拥塞窗口数值。cwnd初始值为1,每经过一个传播轮次,cwnd加倍。 |
---|---|
拥塞避免 | 拥塞避免算法的思路是让拥塞窗口cwnd缓慢增大,即每经过一个往返时间RTT就把发送放的cwnd加1. |
快重传与快恢复 | 在 TCP/IP 中,快速重传和恢复(fast retransmit and recovery,FRR)是一种拥塞控制算法,它能快速恢复丢失的数据包。没有 FRR,如果数据包丢失了,TCP 将会使用定时器来要求传输暂停。在暂停的这段时间内,没有新的或复制的数据包被发送。有了 FRR,如果接收机接收到一个不按顺序的数据段,它会立即给发送机发送一个重复确认。如果发送机接收到三个重复确认,它会假定确认件指出的数据段丢失了,并立即重传这些丢失的数据段。当有单独的数据包丢失时,快速重传和恢复(FRR)能最有效地工作。当有多个数据信息包在某一段很短的时间内丢失时,它则不能很有效地工作。 |
为了防止cwnd增长过大引起网络拥塞,还需设置一个慢开始门限ssthresh状态变量
ssthresh的用法如下:
1、当cwnd2、当cwnd>ssthresh时,改用拥塞避免算法(加法增大)
3、当cwnd=ssthresh时,慢开始与拥塞避免算法任意
发送方判断网络出现拥塞
把慢开始门限设置为出现拥塞时的发送窗口大小的一半。然后把拥塞窗口设置为1,执行慢开始算法
HTTP协议采用 请求 / 响应 的工作方式
具体工作流程如下:
步骤 | 过程简介 | 详解 |
---|---|---|
1 | DNS解析 | 查询DNS,获取域名对应的IP地址; 浏览器搜索自身的dns缓存/搜索操作系统的dns缓存/读取本地的host文件/发起一个dns的系统调用,宽带运营商查看本身缓存 运营商发起一个迭代的DNS解析请求 |
2 | TCP连接 | 浏览器获得域名对应的IP地址后,发起http三次握手 |
3 | 发送HTTP请求 | tcp/ip连接建立起来后,浏览器就可以向服务器发送http请求了 |
4 | 服务器处理请求并返回HTTP报文 | 服务器接受请求,根据路径参数,经过后端的一些处理生成html页面代码返回给浏览器 |
5 | 浏览器解析渲染页面 | 浏览器拿到完整的html页面代码开始解析和渲染,如果遇到引用的外部js,css,图片等静态资源,他们同样也是一个个的http请求,都需要经过上面的步骤 |
6 | 连接结束 | 浏览器根据拿到的资源对页面进行渲染,最终把一个完整的页面呈现给用户 |
HTTP在 应用层 交互数据的方式 = 报文
HTTP的报文分为:请求报文 & 响应报文
下面,将详细介绍这2种报文
HTTP的请求报文由 请求行、请求头 & 请求体 组成,如下图
作用 | 声明 请求方法 、主机域名、资源路径 & 协议版本 |
---|---|
结构 | 请求行的组成 = 请求方法 + 请求路径 + 协议版本 |
示例
设:请求报文采用GET方法、 URL地址 = http://www.tsinghua.edu.cn/chn/yxsz/index.htm;HTTP1.1版本
则 请求行是:GET /chn/yxsz/index.htm HTTP/1.1
组成2:请求头
作用:声明 客户端、服务器 / 报文的部分信息
使用方式:采用”header(字段名):value (值)“的方式
常用请求头
举例:
(URL地址:http://www.tsinghua.edu.cn/chn/yxsz/index.htm)
Host:www.tsinghua.edu.cn (表示主机域名)
User-Agent:Mozilla/5.0 (表示用户代理是使用Netscape浏览器)
其中,响应头、响应体 与请求报文的请求头、请求体类似
这2种报文最大的不同在于 状态行 & 请求行
下面,将详细介绍每个组成部分
组成1:状态行
作用 | 声明 协议版本,状态码,状态码描述 |
---|---|
组成 | 状态行有协议版本、状态码 &状态信息组成 |
状态行 示例
HTTP/1.1 202 Accepted(接受)、HTTP/1.1 404 Not Found(找不到)
组成2:响应头
作用 | 声明客户端、服务器 / 报文的部分信息 |
---|---|
使用方式 | 采用”header(字段名):value(值)“的方式 |
常用请求头
HTTP1.1也是当前使用最为广泛的HTTP协议。 主要区别主要体现在:
区别 | 详解 |
---|---|
长连接 | 在HTTP/1.0中,默认使用的是短连接,也就是说每次请求都要重新建立一次连接。HTTP 是基于TCP/IP协议的,每一次建立或者断开连接都需要三次握手四次挥手的开销,如果每次请求都要这样的话,开销会比较大。因此最好能维持一个长连接,可以用个长连接来发多个请求。HTTP 1.1起,默认使用长连接 ,默认开启Connection: keep-alive。 HTTP/1.1的持续连接有非流水线方式和流水线方式 。流水线方式是客户在收到HTTP的响应报文之前就能接着发送新的请求报文。与之相对应的非流水线方式是客户在收到前一个响应后才能发送下一个请求。 |
错误状态响应码 | 在HTTP1.1中新增了24个错误状态响应码,如409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除。 |
缓存处理 | 在HTTP1.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略例如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略。 |
带宽优化及网络连接的使用 | HTTP1.0中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能,HTTP1.1则在请求头引入了range头域,它允许只请求资源的某个部分,即返回码是206(Partial Content),这样就方便了开发者自由的选择以便于充分利用带宽和连接。 |
区别 | 详解 |
---|---|
端口 | HTTP的URL由“http://”起始且默认使用端口80,而HTTPS的URL由“https://”起始且默认使用端口443。 |
安全性和资源消耗 | HTTP协议运行在TCP之上,所有传输的内容都是明文,客户端和服务器端都无法验证对方的身份。HTTPS是运行在SSL/TLS之上的HTTP协议,SSL/TLS 运行在TCP之上。所有传输的内容都经过加密,加密采用对称加密,但对称加密的密钥用服务器方的证书进行了非对称加密。所以说,HTTP 安全性没有 HTTPS高,但是 HTTPS 比HTTP耗费更多服务器资源。 |
对称加密:密钥只有一个,加密解密为同一个密码,且加解密速度快,典型的对称加密算法有DES、AES等;
非对称加密:密钥成对出现(且根据公钥无法推知私钥,根据私钥也无法推知公钥),加密解密使用不同密钥(公钥加密需要私钥解密,私钥加密需要公钥解密),相对对称加密速度较慢,典型的非对称加密算法有RSA、DSA等。
补充 SSL 与 TLS区别 :后续补充 20200307 (政采云问到了)
1、客户端请求建立ssl连接,并将自己支持的一套加密规则发送给网站
2、网站从中选出一组加密算法与hash算法,并将自己的身份信息以证书的形式发回浏览器。(证书里面包括网站地址,加密公钥、以及证书的颁布机构)
3、获得网站证书之后浏览器要做以下工作:
验证证书的合法性
如果证书受信任,浏览器会生成一串随机数的密码,并用证书中提供的公钥加密
加密好的随机数发给服务器
4、获得到客户端发的加密了的随机数之后,服务器用自己的私钥进行解密,得到这个随机数,把这个随机数作为对称加密的密钥
5、之后服务器与客户之间就可以用随机数对各自的信息进行加密,解密
在HTTP/1.0中默认使用短连接。也就是说,客户端和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接。当客户端浏览器访问的某个HTML或其他类型的Web页中包含有其他的Web资源(如JavaScript文件、图像文件、CSS文件等),每遇到这样一个Web资源,浏览器就会重新建立一个HTTP会话。
而从HTTP/1.1起,默认使用长连接,用以保持连接特性。使用长连接的HTTP协议,会在响应头加入这行代码:
Connection:keep-alive
在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,客户端再次访问这个服务器时,会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。实现长连接需要客户端和服务端都支持长连接。
HTTP协议的长连接和短连接,实质上是TCP协议的长连接和短连接。
HTTP 是一种不保存状态,即无状态(stateless)协议。也就是说 HTTP 协议自身不对请求和响应之间的通信状态进行保存。那么我们保存用户状态呢?Session 机制的存在就是为了解决这个问题,Session 的主要作用就是通过服务端记录用户的状态。典型的场景是购物车,当你要添加商品到购物车的时候,系统不知道是哪个用户操作的,因为 HTTP 协议是无状态的。服务端给特定的用户创建特定的 Session 之后就可以标识这个用户并且跟踪这个用户了(一般情况下,服务器会在一定时间内保存这个 Session,过了时间限制,就会销毁这个Session)。
在服务端保存 Session 的方法很多,最常用的就是内存和数据库(比如是使用内存数据库redis保存)。既然 Session 存放在服务器端,那么我们如何实现 Session 跟踪呢?大部分情况下,我们都是通过在 Cookie 中附加一个 Session ID 来方式来跟踪。
Cookie 和 Session都是用来跟踪浏览器用户身份的会话方式,但是两者的应用场景不太一样。
Cookie 一般用来保存用户信息 比如①我们在 Cookie 中保存已经登录过得用户信息,下次访问网站的时候页面可以自动帮你登录的一些基本信息给填了;②一般的网站都会有保持登录也就是说下次你再访问网站的时候就不需要重新登录了,这是因为用户登录的时候我们可以存放了一个 Token 在 Cookie 中,下次登录的时候只需要根据 Token 值来查找用户即可(为了安全考虑,重新登录一般要将 Token 重写);③登录一次网站后访问网站其他页面不需要重新登录。Session 的主要作用就是通过服务端记录用户的状态。 典型的场景是购物车,当你要添加商品到购物车的时候,系统不知道是哪个用户操作的,因为 HTTP 协议是无状态的。服务端给特定的用户创建特定的 Session 之后就可以标识这个用户并且跟踪这个用户了。
Cookie 数据保存在客户端(浏览器端),Session 数据保存在服务器端。
Cookie 存储在客户端中,而Session存储在服务器上,相对来说 Session 安全性更高。如果要在 Cookie 中存储一些敏感信息,不要直接写入 Cookie 中,最好能将 Cookie 信息加密然后使用到的时候再去服务器端解密。
可以分为5类
类型 | 详情 | 常用的状态码 |
---|---|---|
1xx | 什么都没做直接返回 | HTTP/1.1 200 OK 响应状态行,HTTP/1.1 200 OK |
2xx | 成功返回 | 200 正确 //客户端请求成功,204 服务器成功处理了请求,但是没有返回任何内容 |
3xx | 做了一些事情,没有全部完成 | 301 请求的网页已永久移动到新位置,请求的url已移走 //重定向, 302 请求的网页临时移动到新位置,搜索引擎索引中保存原来的url //重定向 会考到背后的逻辑,304 页面没有改变 |
4xx | 客户端错误 | 400 bad request //客户端请求有语法错误,不能被服务器所理解 ,401 Unauthorized //请求未经授权,403 Forbidden //服务器收到请求,但是拒绝提供服务, 404 未找到页面 //请求资源不存在,410 请求的资源永久删除后,服务器返回此响应 |
5xx | 服务器错误 | 、500 服务器出错.无法完成请求, 503 Server Unavailable //服务器当前不能处理客户端的请求,一段时间后可能恢复正常 |
1、http协议传输的安全问题:网络传输中,通过fiddler或wireshark可以捕获http报文中包含的敏感信息,谈到Java应用安全,主要涉及哪些安全机制?
第一,运行时安全机制 就是限制Java运行时的行为,不要做越权或者不靠谱的事情,在类加载过程中,进行字节码验证,以防止不合规的代码影响JVM运行或者载入其他恶意代码;类加载器本身也可以对代码之间进行隔离,利用SecurityManger机制和相关的组件,限制代码的运行时行为能力,可以看到,Java的安全模型是以代码为中心的,贯穿了从类加载,如URLClassLoader加载网络上的Java类等,到应用程序运行时权限检查等全过程
第二,Java提供的安全框架API,这是构建安全通信等应用的基础(和厂商相关) 加密、解密API/授权、鉴权API/安全通信相关的类库,比如基本HTTPS通信协议
第三, 就是JDK集成的各种安全工具
keytool,这是个强大的工具,可以管理安全场景中不可或缺的秘钥、证书等,并且可以管理Java程序使用的keystore文件。 jarsigner,用于对jar文件进行签名或者验证
2、加密算法能保证密码安全吗?
常见的加密算法有对称和非对称加密
1、对称加密:加密和解密使用相同的密钥加密
前端加密是写在js里,但是js有风险被直接破解从而识别加密算法
2、非对称加密:需要两个密钥,公钥和私钥是一对,如果用公开密钥对数据进行加密,只有用对应的私钥才能解密,
1、https可以保证传输过程中信息不被别人截获,https是应用层协议,下层采用ssl保证信息安全,但是在客户端和服务端,密文同样可以被截获
2、https报文在传输过程中,如果客户端被恶意引导安装了“中间人”的web信任证书,那么https中“中间人攻击”一样会将明文密码泄漏给别人。(数字摘要)
3、结论是:无论http还是https,密码必须密文传输
使用哪个不可逆加密散列函数MD5,并且,使用服务器缓存生成随机的验证字段,并发送给客户端,当客户端登录时,把这个字段一并发送给服务器,用于校验。
方案1:验证码 利用开源的验证码生成工具Kaptcha,在服务端存放生成的验证码值以及一个验证码的生成图片,将图片以base64编码,并返回给view,在view中解码base64并加载图片。
方案2:token令牌
前后端分离场景。用户登录时,根据用户的username作为key,生成随机令牌(例如UUID)作为value缓存在redis中,并将token返回给客户端,当客户端登录时,完成校验,并删除redis的那条缓存记录(或者是设置超期,保存半小时)
1、将重要的cookie标记为httponly, 这样的话Javascript中的document.cookie语句就不能获取到cookie了
(如果在cookie中设置了HttpOnly属性,那么通过js脚本将无法读取到cookie信息,这样能有效的防止XSS攻击)
2、表单数据规定值的类型,例如:年龄应为只能为int、name只能为字母数字组合
3、对数据进行Html Encode 处理
4、过滤或移除特殊的Html标签,例如:
参考资料:1、https://mp.weixin.qq.com/s/pB_xYEFkTIlCTWyGRExy3Q
2、图解http
3、https://snailclimb.gitee.io/javaguide