网络原理
前言
本篇博客将根据现有知识对网络原理做以小结,以下博客仅作为个人学习过程的小结,如能对各位博友有所帮助不胜荣幸。
本篇博客将简单介绍网络的七层/五层模型概念原理应用,以及各个分层的介绍,重点叙述了应用层的HTTP协议与传输层的TCP协议,后期随学习深入还会补充修改。
网络七层/五层模型
OSI七层网络模型
- OSI七层网络模型称为开放式系统互联参考模型,是一个在逻辑上定义的模型
- OSI七层模型是一种理想的框架性设计,其主要功能是区分不同类型的主机数据传输
- 但实际上它并不实用,只是理论上的模型,最为常用的则是TCP/IP五层模型
TCP/IP 五层网络模型
- 应用层:为用户的应用进程提供网络通信服务;
协议——域名系统DNS协议、HTTP协议、HTTPS协议等 - 传输层:负责两台主机之间的数据传输.,将数据从发送端传输到接收端
协议——TCP协议、UDP协议 - 网络层:负责地址管理和路由选择,在众多复杂的网络环境中确定一条合适的路径
协议——IP协议 - 数据链路层:负责设备之间的数据帧的传送和识别,将网络层传递的数据报封装成帧,在同一个数据链路节点的两个设备之间传输
协议——ARP协议、MTU协议 - 物理层:负责光/电信号的传递方式,实现相邻计算机节点之间比特流的透明传输
因为物理层更偏向于硬件,与其他四层区别较大,所以有时也将除物理层之外的其他四层称为四层网络模型
协议的本质就是数据格式的规定,通过一个所有人都认可的协议做到数据的传输
封装和分用
- 封装:当一个数据发送时,它会按照各层从高到低的顺序,按照网络分层的协议包装数据
- 分用:当接收端接收到数据时,会按照从低到高的顺序进行对应网络层的解析
TCP/IP五层网络模型各层代表协议的详解
应用层
- 理解应用层
应用层负责的是程序间的通信,如电子邮件的发送、文件的网络传输、网络远程访问等。应用层所做的事就是当发送一个数据时,发送端先由应用层的协议对其封装,并交由下一次传输层,当经过一系列网络传输,数据达到接收端时,一层层的分用,最后一层再由应用层分用,最终得到数据。
而应用是有不同的场景的,所以应用层协议是有不同种类的,其中经典协议之一的HTTP
就是其中的佼佼者
早期用户,上网使用浏览器来进行上网,而用浏览器上网阅读信息,最常见的是查看各种网页(其实也是文件数据,不过是一系列的 html 文档,当然还有其他资源如图片, css , js 等),而要把网页文件信息通过网络传送到客户端,或者把用户数据上传到服务器,最常用的就是HTTP协议 - HTTP封装后数据报的格式
- HTTP常用方法
其中最常用的方法就是GET方法与POST方法,还有其他的一些特定场合需要用到的方法
GET方法一般用于获取/查询资源信息,而POST方法一般用于更新资源信息
get方法与post方法的区别
1、其对数据长度的限制不同,因为get方法数据存放在URL中,而URL最大长度为2048,而post方法数据在请求体中,无长度限制
2、安全性,由于get方法数据在URL中,很容易被获取安全性较差,而post方法传输数据放在请求体中,较为安全
3、可见性,get方法数据在URL中,对所有人可见,post方法数据则隐藏在请求体中
4、数据类型的限制:因为get方法数据在URL中,以?来分隔URL和数据;以&来分隔参数,所以其数据只能是ASCll字符,post方法在请求体中无限制,允许二进制数据
常见状态码
HTTP常见Header头
- Content-Type:数据类型(text/html/)
- Content-Length:Body(请求体)的长度
- Host:客户端告知服务器,所请求的资源对应的端口号
- User-Agent:声明用户的操作系统和浏览器的版本信息
- referer:当前页面是从哪个页面跳转过来的
- location:搭配3XX转态码,发生重定向时告诉客户端接下来要跳转访问哪里
- Cookie:用于在客户端存储少量信息,通常用于实现会话(session)功能
Servlet
Servlet是一个Java类,用来处理客户端请求并产生动态网页内容
其一个Servlet对象的生命周期:初始化——服务——销毁
init():在第一次创建Servlet时被调用,在整个Servlet生命周期中,仅被调用一次,负责初始化Servlet对象
service():每当请求一个HTTPServlet对象时,该对象的Service()方法就要调用,一般只重写doPost/doGet类似方法
destroy():仅执行一次,在服务端停止且卸载Servlet的时候执行该方法,负责释放占用的资源
基于Tomcat的Servlet处理客户端网络请求并响应的流程:
- Web Client(客户端) 向 Tomcat(Servlet容器) 发出Http请求;
- Tomcat 接收到请求后,将请求解析 创建一个 HttpRequest 对象,
将Web Client 请求的信息封装到该对象里 - 同时 Tomcat 再创建一个 HTTPResponse 对象,用于 Servlet 处理后响应返回给 Web Client
- Tomcat 调用 HTTPServlet 对象的 service() 方法,把 HttpRequest 对象和 HTTPResponse 对象传给 HTTPServlet 对象
- HTTPServlet 对象调用 HTTPRequest 对象的方法,获取Http请求信息
- 经过处理后,HTTPServlet 再调用 HTTPResponse 对象的方法,生成响应数据
- Tomcat 把 HTTPServlet 的响应结果传回给 Web Client
Session和Cookie
Session是指Web系统的会话,指用户登录以后,在退出之前都是一个会话
Session的作用:用户登录时,服务端保存用户身份信息(Map<value,session>),在之后访问的敏感资源的时候,通过请求key = value,服务端通过key对应到value,然后在map中获取到用户的身份信息
Cookie实际上就是一小段文本信息,原理是:客户端本地保存用户的身份信息,然后每次发送HTTP请求时携带该Cookie,用于登录验证
使用场景:登录页面 多少天内免登录 和 记住密码等
- Cookie
HTTP协议是无状态协议,一旦数据交换结束,客户端和服务器的连接就会关闭,HTTP协议对之前处理的事务没有记忆,但访问有些资源时又需要认证用户才能访问,这个过程要一直保持在线状态,而cookie就是一种在浏览器端解决的方案,将登陆认证之后的用户信息保存在本地浏览器中,后面每次发起http请求,都自动携带上该信息,就能达到认证用户,保持用户在线的作用
Cookie本质就是一小段文本信息,客户端请求服务器的时候,如果服务器需要记录该用户,就用response向客户端颁发一个Cookie。客户端会把Cookie保存起来,当再次访问请求这个服务器时,客户端就会把Cookie与URI一起发送给服务器,服务器检查Cookie,以此辨别用户
- Session
Session是服务器使用的一种记录客户端状态的机制,在客户端访问服务器的时候,服务器会开辟一块内存空间,把客户端信息以某种形式(Session对象)记录在服务器上使用,存储结构ConcurrentHashMap,再次访问的时候只需要从该Session中查找用户信息就行
Session实现登录:用户登录时,服务器保存用户的身份信息(Map<value,session>),在之后访问敏感资源时,通过请求 key
= value,服务端通过key对应到value,然后在map中获取用户信息
- Session与Cookie的联合使用
服务器第一次收到请求后,开辟一块Session空间(创建Session对象),同时生成一个Session id,并通过Set-Cookie中的JSESSIONID=xxxxxxx命令,向客户端响应含SessionID的Cookie,客户端收到响应后将其保存到本地,接下来每次想服务器发送请求时,请求头中都会携带Cookie信息,服务器接收到Cookie后解析获取到JSESSIONID的值,得到本次请求的Session id,以此达到认证身份的效果
HTTP协议的特点
- 支持服务器/客户端模式
- 传输较快速,客户端向服务器发送请求,只需要传输请求方法和路径
- 灵活,HTTP允许传输任意类型的数据对象
- 无连接,每次连接只能处理一个请求,服务器处理完客户端请求,客户端收到响应后就断开了连接
- 无状态,协议本身对事务处理没有记忆能力,如果后序连接需要之前发送的信息时就需要重传
HTTPS
- HTTP协议运行在TCP上,使用明文传输,很容易被窃听或侦听,安全性很差
- 而HTTPS协议在HTTP的基础上加了一个SSL的外壳,运行于SSL上,SSL运行于TCP上,信息的加密过程就是在SSL中完成的
HTTPS很大程度上改善了HTTP协议不安全的问题,其保证安全性的方法是传输时通过证书、混合加密等方法来保证安全
- 对内容采用混合加密方法,不在对数据明文传输
- 传输时通过证书来认证对方身份
混合加密技术:使用对称加密与非对称加密技术,
1、服务端先生成私钥然后通过私钥再生成公钥,将公钥放在证书中颁发给客户端
2、使用公钥和私钥以非对称方式生成秘钥
3、客户端使用对称加密,用秘钥对传输数据进行加密
所以网络上传输的数据是被秘钥加密的密文和用公钥加密后的秘钥,以此来保证安全性
HTTPS会先使用公钥和私钥以非对称加密方式生成秘钥,再通过秘钥以对称加密 加密数据进行传输
HTTP与HTTPS的区别
- HTTP是以http://开头的;而HTTPS是以https://开头的
- HTTP是不安全的,信息是明文传输的;HTTPS是安全的,具有安全性的SSL加密传输
- HTTP标准端口为80;HTTPS标准端口为443
- 在OSI模型中,HTTP工作在应用层,HTTPS工作在传输层
- HTTP无需加密,无需证书;HTTPS会先使用公钥和私钥以非对称加密方式生成秘钥,在用秘钥以对称加密方式加密传输数据,也需要证书,这就意味着会消耗更多的CPU资源
传输层
网络传输的五元组
源IP —— 源端口号 —— 目的IP —— 目标端口号 —— 协议号
端口号
端口号标识了一个主机上进行通信的不同应用程序
网络传输时,知道发送端的IP地址后,还需要知道具体由哪个端口(哪个应用程序)发出
接受时同样,通过目的 IP 将数据发送到指定的主机上后,需要在通过指定的目的端口号发送到该主机指定的应用上,最终才算数据传输完成
在TCP/IP协议中, 用 “源IP”, “源端口号”, “目的IP”, “目的端口号”, “协议号” 这样一个五元组来标识一个通信
使用命令查看某个端口
Windows中:netstat - ano | findstr “查看的端口号”
Linux中:netstat - anp | grep “查看的端口号”
传输层中最常见的协议为UDP/TCP协议
UDP协议
特点:
- 无连接:知道对应的IP和端口号就可以直接传输数据,无需建立连接
- 不可靠:没有TCP的确认应答,超时重传等机制,UDP无法得知数据传输是否成功
- 面向数据报发送:应用层交给UDP多长的数据报文,UDP就原样发送,即不会拆分也不会合并,不够灵活
- UDP一次能够传输数据最大长度有限制,不能超过64k
TCP协议
为了解决UDP以上的缺点,因此引入一个更加完善的TCP协议
- 源/目的端口号: 表示数据是从哪个进程来, 到哪个进程去
- 4位TCP报头长度: 表示该TCP头部有多少个32位bit(有多少个4字节); 所以TCP头部最大长度是15 * 4 = 60
- 6位标志位:
URG:紧急指针是否有效
ACK:确认号是否有效
PSH:提示接收端应用程序立刻从TCP缓冲区把数据读走
RST:对方要求重新建立连接; 我们把携带RST标识的称为复位报文段
SYN:请求建立连接; 我们把携带SYN标识的称为同步报文段
FIN:通知对方, 本端要关闭了, 我们称携带FIN标识的为结束报文段 - 16位校验和: 发送端填充, CRC校验. 接收端校验不通过, 则认为数据有问题. 此处的检验和不光包含TCP首部, 也包含TCP数据部分
TCP如何保证数据传输的可靠性
- 通过协议中的校验和序列号
- 确认应答机制:发送数据报携带序号,响应的数据报携带确认序列号,发送端通过响应回的序列号就能得知,上一次数据报是否成功发送
- 超时重传机制:如果主机A在一定时间内(单次传输的最大时间*2),没有收到主机B发来的确认数据报,就会触发超时重传,重新发送数据报
- 连接管理机制:正常情况下,TCP经过三次握手才能建立连接,建立连接后才能发送数据,通过四次挥手才能断开连接
- 流量控制:数据的发送较数据的接收来说非常快,当数据过多,接收端缓存区已满时,就会产生丢包,因此接收端在每次确定应答时,会将自己缓冲区的接收能力放在"窗口大小"中,由发送端控制发送数据的速度
- 阻塞控制:发送端在首次不清楚网络情况等影响数据接收速度时,不会之间将一个很大的数据发给接收端,而是先发送一小块数据,通过响应回的ACK确定传输情况,再决定传输的速度
TCP如何提高数据传输的性能
- 滑动窗口:上面说确认应答时讲到,每一个发送的数据报,都要响应回一个ACK确认应答,发送端收到后再发送下一个数据报,这种机制性能就会很差,而滑动窗口就是无需等待应答可以一次发送多条数据
接收端响应 :响应回ACK的下一个序号是多少,取决于成功接收到的连续数据报的最大序号,也决定了发送端下次数据报要发送的内容,正因为这种确认应答机制,保证了多条数据传输时的安全性
发送端 :滑动窗口下滑传输下一份数据的依赖条件是接收到的ACK数据报,ACK数据报中下一个序号的最大值作为下一个窗口的起始位置
滑动窗口也是一种实现流量控制的机制 :滑动窗口的大小(即每次发送数据的多少)由接收端的缓冲区决定,由此实现流量控制
- 延迟应答:接收端收到数据报后,不用马上返回ACK,而是等待一段时间,让进程有一段时间可以处理缓冲区中的数据,如此一来,响应回的ACK数据报中窗口大小就可以设置更大,从而通过流量控制让发送端的滑动窗口大小设置的更大
- 捎带应答:有些数据报是可以合并的,如响应返回ACK时可以将要发送的数据报,多次网络传输数据合并在一起发送,从而提高效率
详解三次握手和四次挥手
三次握手
- 主机A发送SYN到主机B,请求建立A和B的连接,主机A状态设为syn_sent
- 主机B回复ACK+SYN,响应A的数据报 以及 qinq请求建立B到A的连接,主机B的状态设为syn_rcvd
- 主机A回复ACK,主机A状态设为established,建立A到B的连接
主机B收到主机A回复的ACK,主机B状态设为established,建立B到A的连接
为什么SYN要发送两次?
=> 因为连接是有方向的,需要双方都建立连接
为什么第二步主机B发送数据报时,可以发送ACK+SYN?
=> 本质上时发送两次数据报,但因为发送方向相同且合并无影响,所以可以合并
四次挥手:
- 主机A发送FIN到主机B,请求关闭A到B的连接
- 主机B回复ACK,主机B状态设置为close_wait
- 主机B发送FIN到主机A,请求关闭B到A的连接
- 主机A回复ACK(B向A发送的断开请求),状态设置为time_wait
主机B接收A发送的ACK,状态设置为closed
主机A经过2msl(最长传输时间,超时重传机制)后,状态设为closed
为什么挥手阶段,主机B发送数据报不能合并?
=> 因为第二步回复ACK是TCP在系统内核实现的,自动响应ACK,第三步请求关闭连接是应用程序手动,调用close发送数据报,故两个数据报不能合并
=> TCP这么实现的原因是因为,在程序关闭之前,有时还需要进行释放资源等前置操作,所以不能直接合并发送立即关闭连接
为什么主机A在收到B响应回的数据报后,没有立即关闭?
=> 因为在第三步主机A接收到B的响应后,主机A还需要响应B发送的SYN,而如果A发送完响应直接关闭,第四步的响应如果出现丢包,此时A将无法再次重传
当服务器出现大量close_wait状态,可能是什么原因?
=> 可能是四次挥手阶段出现问题,服务器无法正常关闭连接,检查程序的close方法是否被正常调用
详谈阻塞控制
发送端在不清楚网络状况下,不会贸然的发送大量数据给接收端,因为这有可能导致网络阻塞,TCP引出了慢启动等机制来处理这种情况:
- 慢启动:一开始只发送少量数据,用于检测此时的网络情况,然后逐渐增大每次传输的数据,期初以指数增长
- 阻塞避免:当阻塞窗口达到慢启动的阈值时,传输数据的大小不再时指数增加,而换成线性增加,直到达到窗口最大值触发网络阻塞
- 在每次超时重传后, 慢启动阈值会变成原来的一半, 同时拥塞窗口置回1
当TCP通信开始后, 网络吞吐量会逐渐上升; 随着网络发生拥堵, 吞吐量会立刻下降
拥塞控制, 归根结底是TCP协议想尽可能快的把数据传输给对方, 但是又要避免给网络造成太大压力的折中方案
TCP的粘包问题
基于传输层TCP来实现应用层协议时,因为TCP传输数据都是字节流,读取时需要考虑格式,以及读取的长度,如果长度没有设置好,可能造成粘包问题,原本下一个的数据,被其他地方读取到
解决办法:明确到每个包之间的边界
TCP的长连接与短连接
HTTP的长连接与短连接实质上就是TCP的长连接与短连接
- HTTP/1.0中默认使用短连接:客户端与服务器每进行一次HTTP操作,就建立一个连接,结束后连接断开
- HTTP/1.1起默认使用长连接:就是当一个网页打开以后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,当客户端再次发送HTTP请求时,会继续使用这一条已经建立的连接,长连接也不能永久保持连接,他有一个保持时间
- 在使用长连接时,会在响应头加入 Connection:keep-alive
TCP与UDP的区别?
- TCP有连接,UDP无连接
- TCP传输信息较为可靠,UDP不可靠
- TCP支持一对一通信;UDP支持一对一、一对多、多对一、多对多通信
- TCP面向字节流;UDP是面数据包的
- TCP首部开销大,20个字节,UDP只有8个字节
- TCP可以保证传输的数据顺序,UDP不能
UDP如何实现可靠?
UDP实现可靠就需要解决两个最基本的问题:丢包和包的顺序,这两个可以在应用层实现
1、给数据包进行编号,按照包的顺序进行接收并存储
2、仿照TCP的确认应答机制,在接收端接收到数据包后,向发送端发送确认信息,当发送端收到确认信息后继续发送下一个数据包,否则重传
在浏览器地址输入URL后,按下回车会发生什么?
- 浏览器向DNS服务器请求解释URL中的域名和对应IP
- 根据 IP 和 端口号 ,向服务器发起请求建立TCP连接,发起三次握手
客户端向服务器发送SYN数据报,请求建立连接
服务端接收到后,向客户单发送ACK+SYN数据报
客户端接收到后,向服务端响应ACK数据报
连接连接
- 连接建立后,浏览器向服务器发送HTTP请求
- 服务器解析请求并作出响应,将对应的响应返回给浏览器
- 完成通信后,发起四次挥手,释放TCP连接
客户端向服务端发送FIN数据报,请求关闭连接
服务端向客户端响应ACK
服务端向客户端发送FIN数据报,请求关闭连接
客户端向服务端响应ACK
连接关闭
- 浏览器根据请求得到的响应资源,渲染最终向用户呈现一个完整的页面
网络层
IP协议
网段划分
IP地址分为两部分,网络号和主机号
网络号:保证相互连接的两个网段有不同标识
主机号:同一网段内,主机之间具有相同的网络号,但主机号必须不同
通过合理设置主机号和网络号, 就可以保证在相互连接的网络中, 每台主机的IP地址都不相同
过去曾经提出一种划分网络号和主机号的方案, 把所有IP 地址分为五类,
A类:0.0.0.0到127.255.255.255
B类:128.0.0.0到191.255.255.255
C类:192.0.0.0到223.255.255.255
D类:224.0.0.0到239.255.255.255
E类:240.0.0.0到255.255.255.255
ABC为私有地址,不能连接IntegerIP,主要用于局域网内主机联机
除了私有地址和特殊地址外,都是公网地址
IP地址和MAC地址
MAC:网卡绑定的,在网卡出厂时就固定好,无法更改,物理地址
IP:用来标识网络上某台设备的唯一标识,逻辑地址
IP地址描述的是路途总体的起点和终点,MAC地址描述的是实际传输过程中上每个区间的起点和终点
而网络设备在发送数据时,需要知道MAC地址才能发送
其他协议
- ARP协议:建立主机IP地址与MAC地址之间的关系,在网络通信中,利用ARP通过IP地址和端口号来获取到对应的MAC地址
- DNS域名协议(基于UDP的应用层协议):把域名映射为对应的IP地址
- NAT/NAPT技术:NAT技术可以将私网IP转化为公网IP,NAPT则是将私网IP和端口号转化为公网IP+port
以上便是对网络原理的知识点小结,随着后续学习的深入还会同步的对内容进行补充和修改,如能帮助到各位博友将不胜荣幸,敬请斧正