前言
计算机网络是计算机专业很重要的一门课,课程中详细阐述了两台计算机之间是如何进行通信、如何保证通信的可靠性、如何保证通信的高效性等等内容,在日常coding中可能比较少关注到这方面,但是在真正遇到网络方面的问题无法解决时,了解计算机网络的原理却是十分必要的。
OSI七层网络模型
-
OSI七层网络模型缩略图
-
自底向上理解七层网络模型
工程学科是不断迭代的过程,因此七层协议大概是这么进化来的。
-
物理层
物理层解决了两台机器之间相互通信的问题,首先机器A发送了一些比特流,机器B需要收到这些比特流,这就是物理层所做的事情。物理层主要定义了网络设备的标准,例如接口的类型、机器的类型、网络的类型等。其传输的数据主要是bit流,也就是010101....这类数据,以电流强弱定义,也就是D/A or A/D转换。物理层的分组称为bit。
-
数据链路层
在传输bit流的过程中,会产生错传、数据传输不完整的情况,数据链路层就应运而生。数据链路层主要定义数据格式化传输、以及如何控制对物理介质的访问,通常还有错误控制和纠正,处理错误数据。这一层将分组称为帧。
-
网络层
在数据传输的过程中,需要有数据发送方和数据接收方,而且在网络越来越复杂的变化中,如何在多个节点中找到最佳路径精准地找到接收方,这就是网络层需要做的事。网络层会将网络地址翻译为对应的物理地址,然后通过计算,得出从节点A到节点B的最佳路径,本层的协议是IP协议,在本层中将分组称为数据报。
-
传输层
在网络层传输的过程中,会中断好多次,所以需要把发送的信息切割为一个一个的Segment,分段传输,那么其中一段发送失败了或出现错误了,要怎么办,是否需要重传,这就是传输层需要干的事。传输层保证了传输的质量,这层也被称为OSI七层模型中最重要的一层,本层需要关注的协议为TCP/UDP协议。另外传输层会将数据报进行进一步切割,例如:以太坊无法接收大于1500Byte的数据报,于是传输层就将报文分割为多个报文段,并按顺序发送,并且传输层是负责端到端的传输。
-
会话层
会话层的作用就是建立和管理应用程序之间的通信,无需用户过多地参与到TCP/IP协议中。
-
表示层
表示层可以帮助我们翻译在不同类型网络上的数据,例如加密解密、转换翻译、压缩解压缩等。
-
应用层
应用层规定发送方和接收方必须使用固定长度的消息头,并且封装了各种的报文信息,旨在使用户更方便地应用网络中接收到的数据,该层需要关注的协议为HTTP协议,该层的分组称为报文。
网络数据处理流程为,发送方先自上而下封装,接收方自下而上解封数据。而事实上OSI并没有真正实现网络,而TCP/IP五层模型实际上是对OSI参考模型的实现。
-
TCP/IP协议族
-
传输控制协议(Transmission Control Protocol)简介
- 面向连接的、可靠的、基于字节流的传输层通信协议
- 将应用层的数据流分割成报文段并发送给目标节点的TCP层
- 报文段都有序号,对方收到则发送ACK确认,未收到则重传
-
TCP的报文头
- 源端口:发送方的端口号
- 目的端口:接收方的端口号
- 序号:TCP报文段的序号
- 确认序号:接收方接收到了序号为x的报文段,期待收到序号为x+1为起始的报文段。
- 数据偏移:报文段在整个报文中偏移的字节量
- 保留域:备用区
- 标志位:URG(紧急信息)、ACK(确认标志位)、PSH(为1则收到信息收立即交给进程,无需再队列中等待)、RST(重置标连接)、SYN(请求连接)、FIN(结束连接)
- 检验和:检验数据是否正确
-
TCP的三次握手
TCP是面向连接的协议,在进行三次握手的过程后,TCP将建立一条全双工的连接。为什么要进行三次握手呢?其一,主要是为了确认客户机和服务器同时具备发送和接收的能力,第一次握手,服务器确认了客户机的发送能力,第二次握手,客户机确认了服务器的接收能力和发送能力,第三次握手,服务器确认了客户机的接收能力。其二,是需要初始化seq的序号,以免在正式传输中出现乱序。
三次握手过程如下:
1.客户机首先向服务器发送连接请求,此时SYN标志位为1,且seq=x,x为一个大于等于1的正整数,此时服务器为Listen状态,客户端处于SYN-SENT状态。
2.服务器收到了来自客户机的请求,返回应答,此时SYN标志位为1,ACK标志位为1,ack=x+1(代表期望收到起始为seq=x+1的报文段),seq=y,此时服务器处于SYN-RCVD状态,客户端处于ESTABLISHED状态。
3.客户机收到了服务器返回的应答报文,于是发送自己的应答报文,响应服务器的应答,此时ACK标志位为1,seq为x+1(响应ack需求),ack=y+1(表示期望从服务器获取y+1为起始的报文段),此时服务器处于ESTABLISHED状态。完成三次握手。 -
TCP的四次挥手
四次挥手由客户端或服务端任意一端close。
过程(假设由客户端主动关闭)
1.客户端发送关闭连接请求,此时FIN标志位为1,seq=u。
2.服务端返回应答报文,此时ACK标志位为1,seq=v,ack=u+1(表示期望得到u+1为起始的报文段),等待一段时间,并且传送剩余数据(如果有的话)。
3.服务端发送关闭连接请求,此时FIN标志位为1,ACK标志位为1,seq=w,ack=u+1。
4.客户端返回应答请求,此时ACK标志位为1,seq=u+1,ack=w+1。发送过后服务端立即关闭连接,客户端等待一段时间(2MSL,一分钟左右),确定后续无数据传送,则自行关闭连接。为什么需要有2MSL的等待时间?
1.确保对方收到自己的ACK,如果对方未收到ACK则会重发FIN请求,一来一回正好为2ML。
2.避免新旧连接混淆。为什么需要四次挥手?
因为确保服务器端和客户端都有FIN和ACK。 -
SYN Flood洪泛攻击
其原理是:例用三次握手的规则,在客户机向服务器发送请求后,在服务器发送SYN-ACK后下线,服务器则无法收到ACK确认,服务器段则会不断重试,重试间隔为1s,2s,4s,8s,16s,32s,在linux默认状况下会等待63s,如果有大量的连接重复此过程,则会造成服务器连接队列耗尽,这就是洪泛攻击的原理。
防护措施:linux下设置了TCP_SYN_Cookies参数,若为正常连接,客户机发回SYN Cookie,如果为异常连接,就不发回,但也不会影响到连接队列。
建立连接后客户机突然出现故障:服务器默认“保活机制”,会在一定时间内发送请求,若几次请求无应答,则将该客户机标识为不可达客户机。 -
TCP与UDP区别
首先先看UDP报文头:
UDP报文头由源端口号、目的端口号、报文段长度、检验和组成。长度为8个字节。而TCP为20个字节。
-
UDP的特点
1.面向非连接,传输速度快。
2.支持同时向多个客户端传输信息。
3.报文段报文头只有8个字节,额外开销小。
4.吞吐量只受限于数据生成速率、传输速率以及机器性能。
5.尽最大努力交付,不保证可靠交付,不需要维持复杂的连接状态表。
6.面向报文,不对应用程序提交的信息进行拆分或合并。
结论:
1.TCP面向连接,UDP面向无连接
2.TCP可靠,UDP不可靠
3.TCP有序,UDP可能无序
4.TCP速度慢,UDP速度快
5.TCP重量级,UDP轻量级 -
-
TCP中的滑动窗口
滑动窗口是避免发送方发送过量数据导致接收方缓存无法接收以至于数据丢失的问题,主要在报文头的window字段中,接收方会告诉发送方自己的缓存还可以接收多少数据,而发送方可以根据这一信息,调整自己将要发送的数据。
如上图所示,发送方窗口分为三段:
1.LastByteAcked:最后被确认到的数据位置
2.LastByteSent:已发送的数据的最后一个字节位置
3.LastByteWritten:程序向滑动窗口写入的数据位置
接收方窗口分为三段:
1.LastByteRead:最后被应用程序读取到的数据(已经发送ACK)位置
2.NextByteExpected:收到的但还未发送ACK的数据位置
3.LastByteRcvd:已收到的最后一个字节的位置。
计算方式
接收方还可处理量:AdvertisedWindow = MaxRcvBuffer(最大缓存) - (LastByteRcvd-LastByteRead)
发送方可发送量:EffectiveWindow = AdvertiseWindow-(LastByteSent - LastByteAcked)
解读:
接收方可处理量为 = 最大缓存 - 已收到的报文段(已收到的最后一个字节的位置-程序读取到的数据的位置)
发送方可发送量 = 接收方可处理量 - 待确认量(发送方最后发送的字节位置 - 发送了并且已获取确认的位置)发送方滑动窗口的四类数据:
1.已发送并且被确认的数据
2.已发送但未得到确认的数据
3.未发送但接收方同意发送的数据
4.未发送且接收方拒绝的数据
接收方滑动窗口三类数据
1.接收且已确认的数据
2.未接收但可以接收的数据
3.未接收且无法接收的数据
当接收方滑动窗口不足时,发送方是不会移动自己的滑动窗口的,只有当发送方的滑动窗口之前的所有数据都被确认,发送方的滑动窗口才会向后移动,这也是TCP保证数据完整性的重要手段。
HTTP协议
-
HTTP简介
HTTP:超文本传输协议
1.支持客户/服务器模式
2.简单快速
3.灵活
4.无连接:限制每次连接只处理一个请求,但从HTTP1.1起,默认使用长连接。
5.无状态
HTTP版本现在有常用的1.0和1.1,还有2.0,1.1在1.0的基础上做了keep-alive长连接技术,而2.0虽然在各种思想上都显得更加合理,但是1.1基本能满足日常需求且更换2.0消耗大,所以2.0目前并没有推广开。 -
HTTP请求报文
请求行:请求方式 url 协议版本
头部字段名:值
......
头部字段名:值
请求正文例如:
POST /user HTTP/1.1 //请求行
Host: www.baidu.com
Content-Type: application/x-www-form-urlencoded
Connection: Keep-Alive
User-agent: Mozilla/5.0. //以上是首部行
(此处必须有一空行) //空行分割header和请求内容
name=world 请求体 -
HTTP报文头
请求/响应的步骤
1.客户端连接到Web服务器
2.发送HTTP请求
3.服务器接受请求并返回HTTP响应
4.释放TCP连接(如果是keep-alive则保持一段时间)
5.客户端解析HTML内容-
关于HTTP的面试题
1.在浏览器地址栏键入URL,按下回车后经历的流程。
答:首先要进行DNS解析,将访问的域名解析为IP地址,解析是由近到远的,首先在浏览器缓存中寻找是否有对应的IP,如果没有则进入系统缓存,如果没有则按照路由器缓存->IPS服务器缓存->根域名缓存->顶级域名服务器缓存,这样一路查找,直到找到了则停止查找,直接返回。然后进行TCP连接,默认端口80,进行三次握手(可以简单描述三次握手的流程),建立连接后发送HTTP请求,服务器处理请求并返回HTTP报文,浏览器解析并渲染页面,最后连接结束。2.常见的HTTP状态码。
答:先分类。
1xx提示信息--表示请求已接受,继续处理
2xx表示成功连接
3xx重定向--要完成请求必须进行更进一步操作
4xx表示浏览器(客户端)出现错误
5xx表示服务器端出现错误
常见的HTTP状态码:
200 ok,成功连接
400 bad request(客户端请求语法错误,服务器无法理解)
401:未经授权
403:拒绝服务
404:Not Found
500内部服务器错误
503:当前不能处理,一段时间后可能3.GET和POST请求的区别。
答:1.HTTP报文层面:GET请求信息放在URL后(?XXX=XXX&XX=XXX),POST放在报文体,安全一些(但其实没什么区别,抓包可以直接抓到报文)
2.数据库层面:GET符合幂等性(对数据库一次或多次操作,结果是一致的)和安全性(对数据库一次或多次操作,没有改变数据库中的数据),GET是做查询操作的,不会改变数据库中的数据。
3.POST插入,每次请求都有可能不一样。
其他层面,GET可以被CDN缓存,被存储,在服务量巨大的环境下,又有大部分的数据是只读的,所以我们并不想让服务器完全处理,就可以使用GET请求,但POST不行,POST必须交由服务器处理。4.Cookie和Session的区别
Cookie是客户端解决方案,由服务器发给客户端的特殊信息,以文本的形式存放在客户端。
Cookie使用过程:
1.用户向服务器发送个人识别信息,服务器也向客户端发送Cookie文件。
2.客户端再次发送请求时,也会把cookie发送回去。
3.服务端会获取cookie从而生成与客户端相对应的内容。
Session 服务端解决方案,Session是在服务器上保存的信息。服务器解析客户端请求并操作SessionId,按需保存状态信息。如果客户端包含SessionId则直接使用,如果不包含则创建一个。
Session实现方式:
1.使用Cookie实现
客户端向服务端发送请求,服务端返回响应报文并SetCookie,Cookie中含有JSESSIONID-XXXXX,客户端之后的每次请求都会携带这个Cookie,服务端根据这个Cookie中的Session提供响应的内容。
2.使用URL回写实现
使用URL回写即在URL地址中携带JSESSIONID这个参数。
Tomcat同时支持Cookie和URL回写,默认使用Cookie,当浏览器拒绝Cookie时,则使用URL回写的方式实现Session
区别:
Cookie是以文件的形式存储在客户端,而Session是在服务器端进行处理的,Session相对Cookie来说比较安全,因为Cookie存储在客户端,容易被修改,而Session存在于服务器端,无法被修改,但Session会占用服务器资源,影响服务器性能,如果考虑服务器性能优先,则可以考虑多使用Cookie。 -
HTTP和HTTPS区别
HTTPS:超文本传输安全协议
HTTP:HTTP+TCP+IP
HTTPS:HTTP+(SSL OR TLS)+TCP+IP
要说HTTP和HTTPS的区别首先要提到SSL和加密方式。 -
SSL:Security-Sockets-Layer,安全套接层
SSL是为网络通信提高安全及数据完整性的一种安全协议,是操作系统对外的API,SSL3.0后更名为TLS,采用身份验证和数据加密保证网络通信安全和数据的完整性。
-
加密的几种形式
-
1.对称加密
对称加密是一种可以进行解密的加密方式,其特点就是,将一个数据按照一定过程加密,那么按照这个过程的反过程一定可以将这个数据进行解密。其特点是效率高,但安全性低。 -
2.非对称加密
非对称加密的特点是加密使用的密钥和解密使用的密钥是不相同的,即,将一条数据按照一定的过程进行加密,按照这个过程的反过程并不能逆推回加密数据的源数据,而只能通过另一种特定的方式进行解密,这就是非对称加密。非对称加密的安全性高,但效率不如对称加密。 -
3.Hash加密
Hash加密,将任意长度的信息转换为固定长度的值,其加密的数据是不可逆的,一般日常所用的加密方式是MD5方式。 -
4.数字签名
在信息后加一段Hash值,证明某个消息或文件时某人发出的,且可以证明信息没有被修改。
-
1.对称加密
-
HTTPS使用的加密方式
HTTPS使用证书+各种加密方式共同加密
加密的三次握手过程:
1.浏览器将支持的加密算法信息发送给服务器
2.服务器选择一套浏览器支持的加密方式,以证书的形式回发给浏览器。包含CA机构,公钥,有效期,所有者等。
3.浏览器验证证书的合法性,并结合证书公钥,加密信息发送给服务器。
4.服务器使用私钥解密,验证hash,加密响应消息回发浏览器
5.浏览器对响应消息进行解密,并对消息进行验证,之后进行密文交互数据。 -
区别
HTTPS需要到CA申请证书,而HTTP不需要。
HTTPS的证书是需要收费的,HTTP不收费。
HTTPS默认端口为443,HTTP默认端口为80。
HTTPS为有状态协议,HTTP为无状态协议。
虽说HTTPS是安全协议,但是HTTPS也未必安全,在浏览器默认填充http:// 的情况下访问https的网站,请求需要进行跳转,这个过程中就有被劫持的风险。但可以使用HSTS优化(自行了解)。
Socket
-
Socket概念
Socket是对TCP/IP协议的抽象,是操作系统对外开放的接口,如果一定要按层次来理解Socket的话,Socket位于传输层之上,应用层之下。可以把它理解为一扇门,各种请求可以通过这扇门和和系统进行通信。
-
Socket 通信流程
-
Socket 通信原理
我们知道,在进程间通信我们可以通过管道、共享内存等等等等方式,但是无论使用哪一种方式,通信的本质都是需要被通信的对象有一个可以唯一标识的标识符。在进程间通信时,进程的标识符为PID,而在网络通信中,我们首先要使用IP标识主机,TCP+端口号标识进程。而端口号就相当于门牌号,Socket可以监听某个端口来使该进程与某个请求进行交互。而Socket是基于Unix而生的,Unix奉行的宗旨就是,一切皆文件,所以Socket的本质就是在读写特定的Socket文件,以达到通信的目的。
结语
通过上文的叙述,可以大概了解OSI七层网络模型的“各司其职”、了解TCP/IP协议族、还有三次握手四次挥手的整个过程、了解洪泛攻击的原理、TCP/UDP的区别以及TCP中拥塞控制之滑动窗口,还了解了HTTP协议以及HTTP安全协议——HTTPS,还稍微谈到了点Socket。
计算机网络是一门大的学科,上面所说的也不过百分之二三,寥寥而已。但是基本可以满足日常开发所需。
本文图片来自网络,侵删。
欢迎大家访问我的个人博客:Object's Blog