网络
1.网络名词解释
1. IP地址和端口号
在网络中唯一标识一台主机 ,这是一个逻辑地址;(IPV4 / IPV6)
目前主要使用的是IPV4,IPV6不能向前兼容IPV4,所以没得到广泛使用
在网络中的每条数据中都会包含两条信息:源端IP地址,目的端IP地址
PORT端口 :在一台主机上唯一标识一个进程 (范围:0~65535)
2. 网络协议
网络协议 :通信双方数据格式的约定,在通信领域,他是为了保障通信能够按照既定流程进行,而给参与各方的一套标准;
协议分层 :
协议的封装,在整个通信环境中使用起来更加方便
协议栈: 由框架和协议共同构成协议栈,如OSI、TCP/IP;
3. OSI七层参考模型
1. 介绍
尽管TCP/IP协议栈及其对应的分层模型在实际应用中大行其道,但人们在谈论技术的时候最频繁引用的就是OSI模型,它的最大贡献就是将协议、接口、服务进行相互独立;
(说白了就是实际用的少,分层太啰嗦,但是学术理论性较强,值得学习⭐)
OSI模型最大的特点就是将协议、服务和接口进行相互独立;
2. 为什么OSI模型没得到广泛运用?
上面说到,OSI并没有得到广泛运用,这里总结如下:
- 把服务划分的过于琐碎,导致表示层和会话层大体处于空白;
- OSI模型的定义先于OSI模型中协议的定义,这让OSI模型多少有一些纸上谈兵;
3. 每层含义
- 应用层:应用层的服务是提供用户接口,所以用户层中包含了各类用户常用的协议;
- 表示层:表示层的服务是既保证通信各方在应用层相互发送的信息可以相互解读,也保证双方在信息的表达方式上是一致的,如加密解密、压缩解压、编码方式转换等属于表示层的服务;
- 会话层:会话层的服务是完成各方交互信息之前的会话建立准备工作,这里的工作包含确认通信方的身份,确认通信方可以执行的操作等,因此如AAA中的认证 、授权等功能皆属于会话层的服务;
- 传输层:传输层的服务是规范数据传输的功能和流程,因此,这一层的协议会针对是否执行消息确认、如何对数据进行分片和重组等制定标准;传输层的交换单元叫段,即经传输层协议封装后的数据称为数据段(Segment); ⭐
- 网络层:网络层的服务是将数据从源转发给目的设备;由此可知,这一层的协议需要定义如地址格式、寻址方式等标准;网络层交换单元的名称是包,即经网络层协议封装后的数据称为数据包(Packet);
- 数据链路层:数据链路层的服务是为相邻设备或处于同一个局域网中的设备实现数据帧传输,并对传输的数据帧进行校验和控制;经数据链路层协议封装后的数据叫数据帧;
- 物理层: 物理层的服务是实现信号在两台相邻网络实体之间的传输;物理层交换的单元名称是比特;
4. TCP/IP模型 (⭐)
1. TCP/IP和OSI的联系与区别
-
两者联系:网络模型的作用都是为了规范通信流程;
-
这两个模型的根本区别就在于建立标准的方式,也就是上面谈到的OSI是先定义于OSI模型各层对应协议的定义,也就是说OSI模型是在缺乏对各层协议的充分了解下定义的,因此使用现有的协议和OSI模型来构建网络往往会出现无法满足服务规范的情况;
-
而TCP/IP协议相反,这个模型一开始就是对TCP协议和IP协议所作的描述,因此该模型定义的服务与TCP和IP协议高度吻合;而且TCP/IP协议栈中还有很多协议是先在一些设备上进行使用并实现了通信,然后再一边使用一边制定具体的协议规范;
2. 每层含义
- 应用层:负责应用程序之间的数据沟通; HTTP/FTP
- 传输层:负责端与端之间的传输; TCP /UDP
- 互联网层:与OSI中的网络层差不多,目的都是让数据实现从源地址到目的地址的正确转发,负责地址管理与路由选择 ; IP协议就是这一层的协议
- 网络接入层:可以视为是主机与线路之间的接口,这一层与OSI最下面两层功能相似,但是TCP/IP模型的网络接入层没有制定通过介质传输信号时所用的协议;
3. TCP/IP模型的不足
可以看到,TCP/IP将OSI的应用层、表示层、会话层归纳到了应用层,这样做是合理的,然而将数据链路层和物理层归纳到一起是不行的,会造成一定的混淆,毕竟这两层在通信中扮演的角色截然不同 ,所以也出现了TCP/IP 5层模型,即是将网络接入层还是分开成数据链路层和物理层;
2. 数据传输流程
这里我将结合上面的TCP/IP模型和一些协议来讲解数据在一次通信中如何被处理的;
1. 封装与解封装
-
封装: 很少人愿意在直接在自己的包裹上写上收件人的名字、是否加急、是否在对方收到时给自己发送短信,所以需要在包裹上贴一张快递单;
同理呀!要传输的数据本身也不会附带一段信息来描述目的地、数据类型、是否加密、如何加密解密等,因此要传输数据,也必须在数据上添加相应的信息,至于添加甚麽样的信息、甚麽样的长度和格式等具体的标准,要由对通信进行标准化的协议来进行定义,而这正是协议兑现服务的方式;
然后传输设备根据协议向数据负载中添加功能性信息的操作称为封装;
注意上图:为了突出头部封装的过程,图中没有包含将一整段信息拆分成多个数据包的处理过程,也没有考虑协议给数据包封装尾部的情况;
- 解封装: 当接收方通过接口接收到发送方经过层层封装的数据之后,它需要再从下到上根据各层的协议,去掉发送方添加的头部信息,将数据层层还原为发送方最初要传输的数据,这个过程称之为解封装;
2. 具体流程⭐
举个栗子吧,假如数据从A传送到C,流程如下:
- 先将数据从上而下层层封装,最终封装成如下数据帧:
- 当交换机A接收到了终端A的数据后,会对数据最外层的以太网头部信息进行查看(并没解封),了解数据的目的硬件地址,在看到数据目的硬件地址之后将该数据帧(数据链路层封装后的数据叫数据帧)发送给路由器A,所以交换机不会对数据帧进行解封装;
- 当数据帧来到了指定的路由器(A)后,路由器也会查看最外层封装的以太网头部信息,当发现这里的目的硬件地址是自己时,路由器就会将以太网头部进行解封装,查看数据的逻辑地址(IP头部中查看,即目的IP地址),在看到目的IP地址后,根据查询路由表发现,要想将数据发送给终端C,就得转发给路由器B,因为要发送给路由器B,路由器B跟路由器A不在一个局域网(以太网)中,所以再封装的时候不是封装一个以太网头部,而是封装一个PPP头部,里面是路由器B的一种代表地址,然后将这个封装后的数据帧再通过PPP链路发送出去;
- 当路由器B接收到这个数据帧,首先对最外层的PPP头部进行解封装,当路由器B看到IP头部的目的逻辑地址是终端C时,又通过查询路由表发现:要想将数据发给C,就得先发送给交换机B,从与交换机B相连的以太网接口发送出去,于是路由器B 使用终端C的硬件地址来为数据包封装以太网头部,并将封装后的数据帧发送给交换机B ;
- 此时数据帧到了交换机B,由于交换机不具备互联网层的功能,所以只对以太网头部进行查看(不解封),看到该数据在这个以太网中的目的地址是终端C之后,就会将数据从与C相连的接口发送出去;
- 终端C收到数据后,自下而上解封装数据,最后还原为最初的数据;
综上,我们可以得出如下结论:
- 交换机属于网络接入层,即OSI中的数据链路层,所以叫二层设备;
- 路由器属于互联网层,即OSI中的网络层,所以属于三层设备;
1.应用层
应用层知名协议:HTTP、FTP、DNS、DHCP
1. HTTP协议
1. 概述
所谓协议,就是规定的意思,HTTP协议就是HTTP规定的意思,它定义了两台设备之间交互网页信息的流程;
- HTTP协议提供的服务是在HTTP客户端和HTTP服务端之间传输信息;
- HTTP协议运行于TCP协议之上,HTTP访问默认使用TCP80端口,由TCP协议为HTTP信息传输提供可靠性保障以及拥塞管理等服务;因此在客户端和服务器之间要通过HTTP来传输信息之前,他们之间首先要建立好TCP连接;
HTTP协议是基于CS架构进行通信的
2. 版本更新特点
最初版本HTTP1.0:
当TCP连接建立起来后,客户端只能向服务端发送一条HTTP请求,当服务器用被请求的内容对该消息做出响应后,这条TCP连接就会断开,如果双方还需要通信,则需重新建立连接;
现在的版本HTTP1.1(持续更新中):
客户端和服务端建立一条TCP连接后,可以复用这条TCP连接发送多个请求-响应消息,甚至客户端可以在前一个请求尚未收到响应消息之前就能发送下一个请求消息;
注意:由于使用HTTP1.1协议进行通信的客户端和服务器并不知道这个为了传输消息而建立的持续TCP连接应该维持多久,因此HTTP1.1服务器需要设置一个时间间隔,指定一段时间没有接收到HTTP请求消息的连接应当断开;因为对于HTTP服务器而言,与一台客户端长期保持TCP连接却不传输消息会耗掉大量资源;
3. URL(统一资源定位符)
网址——URL(统一资源定位符):https://www.baidu.com (下面这个是一个完整的URL结构)
http://user:pass@www.hello.cn:80/dir/index.html?uid=1#ch1
协议方案名称😕/用户名:密码@服务器地址:端口号/请求资源路径?查询字符串#片段标识符
URL编码/解码 (urlEncode,可以搜这个进行在线转换)
查询字符串是用户提交给服务器的数据信息,这些提交的信息中若是出现特殊字符,则有可能与URL中的间隔符
4. HTTP协议格式(4部分)
1. 格式
协议分为请求和响应,对应的如下:
-
首行:
-
请求首行 (格式:请求方法 URL 协议版本)
请求方法:GET/POST(等等,不止这两种) 区别:GET没有正文,提交的数据在URL的查询字符中
协议版本:0.9/1.0/1.1/2 (可以去搜索各大版本的区别特性) -
响应首行 (格式:协议版本 响应状态码 状态码描述信息)
响应状态码(五大类):例如:1** / 2** / 3** / 4** / 5**
1** :通常是一些描述信息,服务器收到请求,需要请求者继续执行操作
2** :正确处理了你所请求的信息,已经OK了,常见的有 200
3** :重定向 (已经接收到你的信息,但让你转接到另外一个地址,这个地址在Location中)
4** :常见的有404,即请求资源不存在
5** :返回的是服务端错误状态码了解网站 :https://www.runoob.com/http/http-status-codes.html
-
-
头部 (对应请求头和响应头)(下列没标明的既存在于请求头也存在于响应头)
以一个个key:value组成的键值对,并且各个键值对以\n或\r分隔
(注意:每个HTTP报文不是包含下面所有,根据需求来)常见请求头:
- Host:主机地址 (请求头)
- Connection:标明是长连接还是短连接 (请求头)
- Cookie:已有的Cookie (请求头)
- User-Agent :用户标识,例如OS和浏览器的类型和版本(请求头)
- Accept:标明客户端可以接受的数据(图片、视频、…)
- Referer:表明从哪一个地址跳转到当前页面的,作用有记录访问来源
常见响应头:
- Set-Cookie:(会话信息),特指保存在客户端的信息 ,典例是网站不用每次都登陆 (响应头)
- Session :特指保存在服务端的信息
- Location :重定向 (响应头)
常见通用头:
- Content -Length /Transfer-Encoding :请求体/响应体的长度,单位是字节
- Content-Encoding:请求体响应体的编码格式
- Cache-Control:取值一般为no-cache或max-age=xx, xx为一个整数,表示该资源缓存有效期
- Content-Type :请求体/响应体的类型,例如:text/plain(纯文本格式),text/html(html格式)
在这里,提一下Session和Cookie:
Cookie:在网站中,http请求是无状态的(⭐)。也就是说即使第一次和服务器连接后并且登录成功后,第二次请求服务器依然不能知道当前请求是哪个用户。cookie的出现就是为了解决这个问题,第一次登录后服务器返回一些数据(cookie)给浏览器,然后浏览器保存在本地,当该用户发送第二次请求的时候,就会自动的把上次请求存储的cookie数据自动的携带给服务器,服务器通过浏览器携带的数据就能判断当前用户是哪个了。cookie存储的数据量有限,不同的浏览器有不同的存储大小,但一般不超过4KB。因此使用cookie只能存储一些小量的数据。
Session:session和cookie的作用有点类似,都是为了存储用户相关的信息。不同的是,cookie是存储在本地浏览器,而session存储在服务器 (⭐)。存储在服务器的数据会更加的安全,不容易被窃取。但存储在服务器也有一定的弊端,就是会占用服务器的资源,但现在服务器已经发展至今,一些session信息还是绰绰有余的。 -
空行
\r\n -------用于间隔头部与正文 -
正文 (GET提交的请求没有正文)
2. 常见的HTTP请求方法(HTTP操作命令)
在HTTP请求报文的首行的请求方法,有如下几种:
HTTP操作命令 | 解释 |
---|---|
GET | 读取页面,一般来说GET方法应该只用于数据的读取,而不应当用于会产生副作用的非幂等的操作中。它期望的应该是而且是安全的、幂等的。这里的安全是指。请求不会影响到资源的状态 |
HEAD | 读取页面头部,类似于GET,只不过返回的响应中没有具体的内容,用于获取报头 |
POST | 向服务器传输附加信息进行处理请求(例如提交表单或者上传文件);数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改 |
PUT | 写入页面 |
DELETE | 删除页面,用于请求服务器删除所请求的URL所标识的资源。DELETE请求后指定资源将会被删除,DELETE方法也是幂等的 |
CONNECT | 通过代理连接 |
TRACE | 将客户端发送的请求发回,用于测试或诊断 |
OPTIONS | 请求可用选项的信息,即允许客户端查看服务器的性能 |
3. 抓包解析
下面是我在我学校教务处系统的登陆界面抓取的一个http数据包(只截取了请求和响应部分,没截取正文。正文就是我那个登陆界面的源码):
GET http://59.74.168.16:8989/ HTTP/1.1
Host: 59.74.168.16:8989
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Referer: http://jwc.xust.edu.cn/
Connection: keep-alive
Upgrade-Insecure-Requests: 1
HTTP/1.1 200 OK
Cache-Control: no-cache, no-store
Date: Tue, 23 Jul 2019 03:33:54 GMT
Pragma: no-cache
Content-Length: 6610
Content-Type: text/html; charset=gb2312
Expires: -1
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
Set-Cookie: yunsuo_session_verify=66b6530ff0a2386af2c269b0e7619959; expires=Fri, 26-Jul-19 11:33:54 GMT; path=/; HttpOnly
X-AspNet-Version: 1.1.4322
P3P: CP=CAO PSA OUR
Set-Cookie: ASP.NET_SessionId=slgkn555unoeljqlcieidpae; path=/
可以看到,上面的一部分是我们的请求信息:第一行是请求首行,后面的都是请求头
Host对应的是我教务系统的主机地址、referer对应的是我上次是从哪个地址跳转过来的,Accept-Encoding对应的是浏览器端能接受的一些编码格式,其他就不一一叙述了
下面一部分就是响应信息:第一行是响应首行,后面对应的是一些响应头
注意:每个包根据需求对应都会有不同的头部信息(响应头和请求头)
4. GET和POST的区别(⭐)
- GET和POST方法其实没有本质区别,只是报文格式不同;
GET和POST只是HTTP协议中两种请求方式,而HTTP协议又是基于TCP的应用层协议,它们都是用的同一个传输层协议,所以在传输上,并没有区别; - 在报文格式上:不带参数时,HTTP请求首行不同而已
带参数时:GET方法的参数应该放在URL中,POST方法参数放在请求体中;
(因为两种方法本质都是TCP连接,所以你也可以在使用GET方法时,把参数放在请求体,或者在使用POST方法时,把参数放在URL中,但这需要服务端的支持,也就是说,服务端在读取的时候设置好了一定的格式,按照指定来的) - 缓存(Cache):GET方法提交能被缓存,而POST不能被缓存,这也意味着GET提交的参数能被保留在浏览器历史,而POST不能
- 安全性:与POST相比,GET的安全性较差,因为所发送的数据是URL的一部分,在地址栏上就可见;相对而言,POST方式更加安全,因为参数不会被保存在浏览器历史或web服务器日志中
但真正的安全性来讲:GET和POST都是不安全的,因为HTTP在网络上传输是明文的,上面讲了,数据信息一个在URL中,一个在请求体中,这样我们直接利用抓包工具就可轻而易举的得到HTTP的报文信息,在HTTP的请求信息中,就包含了URL和请求体,这样数据就暴露了;
要想安全传输,就得加密,也就是用到HTTPS; - **对数据长度的限制:**GET提交时把数据放在URL中,而URL长度受到一定的限制;而POST把数据放在请求体中,对数据长度没有限制(所以传输较大数据用POST请求方法);
但在HTTP协议的标准文档中,并没有对URL的长度给与限制,对URL长度的限制是来源于浏览器和服务器,服务器对URL的限制考虑于处理较长的URL要消耗较多的资源,为了性能和安全(防止恶意构造较常URL); - **对数据类型的限制:**由于GET方式的数据放在URL中,所以只允许ASCLII字符;**而POST方式对数据没有限制,数据存放在请求体中,在POST提交中,请求头Content-Type指定请求体的类型,**例如文本格式还是HTML格式等等,这样服务端在读取的时候,用请求头Content-Type来进行解析
额外问题:
-
POST方法会产生两个TCP数据包?
答案:有的人实践得到,POST方法将头部信息和请求体分开发送,其实不一定,HTTP协议中并没有这样规定,根据浏览器不同,结果不同; -
GET用于获取信息,POST用于提交信息?
答案:它们都是HTTP请求的方式,那么当然,都可以用来请求获取信息,例如在POST的请求体中为空,即不提交任何内容,但服务器收到POST请求也会传回响应信息;
5. HTTPS和HTTP的区别
- HTTP协议为超文本传输协议,信息为明文传输;HTTPS为超文本传输安全协议 ,它是具有安全性的SSL(安全套接层)加密传输协议;
- HTTP和HTTPS使用完全不同的连接方式;客户端在发起HTTP连接时默认会连接服务器的TCP80端口,而发起HTTPS访问时连接服务器的TCP443端口;
- https协议需要到CA(证书授权中心)申请证书,因为在进行SSL连接时客户端需要得到服务端的CA证书(里面包含着服务端的公钥,后面需要它来加密);
- HTTPS就是在HTTP和TCP之间多了一层SSL协议,这层协议专门用来进行加密操作,提供安全保障;
- 状态不同:HTTP的连接很简单,是无状态的。而HTTPS协议是SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,要比HTTP协议安全;
对于HTTPS具体的加密过程,这里提供一篇较为权威的博客链接:
https://www.cnblogs.com/jesse131/p/9080925.html
2. 传输层
2.1 概述
功能:负责端与端之间的数据传输;不关心数据是如何传输的;
主要协议: TCP/UDP ,传输层协议只在终端系统中工作,只负责将应用程序需要发送的数据转交到网络层,反之亦然;
端口 :
- 在一个主机上标识一个进程(标识接受到的数据应该交给哪个进程处理一个端口只能被一个进程占用 ;一个进程可以使用多个端口 ;
- uint16_t——无符号16位整数
- 端口号:0~65536 ,0~1023不推荐使用
五元组 :在网络通信中,每一条数据都必须带有以下关键信息 :(用于标识网络中的一条通信)
- 源IP地址
- 源端口
- 目的IP地址
- 目的端口
- 协议
2.3 TCP协议
2.3.1概述:
全称为传输控制协议,负责为不同终端系统的应用进程之间提供面向连接的通信服务,是一种可靠的传输层协议;
- 面向连接,可靠传输,面向字节流
2.3.2 特性
在为应用进程之间建立通信之前,TCP协议需要首先建立传输数据所需的连接 。一但TCP连接建立成功,应用进程之间就可以借助这条TCP连接相互发送上层数据了。此外,TCP协议能够对它所建立的TCP连接进行控制,包含下面几点:
- 对数据执行分割和重组 :每次传输都会对数据包负载有大小限制,应用层只管将数据统统发给TCP协议,而TCP能够将数据进行合理分割,同等的,在接收端TCP也能将数据进行合理重组;
- 确保数据按顺序传输 :发送端的TCP协议会为自己发出的数据标明序列号(seq),这样在接收端TCP协议就能够对数据进行重新排序,确保了数据的有序传输;
- 同时为多个应用程序提供传输服务
- 确认接收方收到数据并按需传输:TCP协议的可靠性正是源于这一点,TCP协议规定,在接收方接收到数据后一定要向发送方进行确认,如果发送方没有收到接收方的确认,就会把未确认的数据进行重发
- 控制传输速率:通过滑动窗口来实现;设想接收方的接收速率远远低于发送方的话,接收方接受不到许多数据,这样发送方就会进行重传,从而造成恶性循环,网络中充斥着重复的数据,即占用带宽,又毫无意义;
当然,这些只是TCP为应用进程提供的一部分服务,要了解更多,可自行查阅TCP官方文档;
2.3.3 TCP连接(三次握手)
刚刚上面描述了,在TCP通信之间需要建立一条TCP连接;TCP连接建立完成后,终端之间就可以进行数据传输,注意在数据传输完成后,TCP会进行断开连接的过程(四次挥手)
所谓三次握手,先来看三次握手和四次挥手的总流程图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LUTLsRAD-1574557550144)(C:\Users\Laptop\AppData\Local\Temp\1563162227705.png)]
- 为什么握手是三次而不是两次
- 两次不安全,有可能SYN会延迟,缺乏状态保护的情况下,收到一个SYN就会建立一个新的socket,完整的状态保护避免对一个客户端创建多个socket ;有了三次握手,在收到第一个SYN后,此时服务端就等待客户端的ACK回复确认,这期间就算收到了客户端的新的SYN也不会理睬,就不会创建新的socket;
- 两次不安全,服务端无法通过客户端的SYN确定客户端具有数据收发能力,需要再次进行确认;
除了上面我总结的,在教科书里,是这样解释的(其实意思也差不多,这里给出来供大家衡量参考)
《计算机网络》第四版中讲“三次握手”的目的是**“为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误”** 书中的例子是这样的,“已失效的连接请求报文段”的产生在这样一种情况下:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。”。主要目的防止server端一直等待,浪费资源。
- 挥手为什么是四次
- 被动关闭方,收到FIN之后对其进行ACK回复,但是不能直接关闭socket,因为这时候用户有可能正在处理数据(socket接受缓冲区中有可能还有堆积的数据),需要用户来确认什么时候关闭socket发送FIN;因此ACK和FIN不能放在一起;
- 为什么建立连接是三次握手,而关闭连接却是四次挥手呢?
- 这是因为服务端在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。而关闭连接时,当收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,己方也未必全部数据都发送给对方了,所以己方可以立即close,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送。
- 若是三次握手失败,服务端如何处理?
- 服务端超时等待之后,向客户端发送rst报文,然后释放新建的socket资源
SYN泛洪攻击-----------调研
主动关闭方TIME_WAIT状态的作用:
假设没有time_wait而是直接进入closed状态,释放socket资源造成的危害:
在主动关闭方发送的最后一次ACK丢失的情况下:如果客户端使用相同的地址信息立即重启,但是被动关闭方:
收到被动关闭方超时等待后重发的FIN包,对新连接赵成影响;
发送SYN请求,但是对方等待的是ACK,因为状态不对导致对新连接的影响
因此主动关闭方需要等待一段时间:若是对方重发FIN请求,可以对其再次进行确认回复
MSL:报文最大生命周期 (30秒)
等待两个MSL时间是为了让网络中延迟的报文都消失网络中不会对后续连接造成影响
大量time_wait解决方案:调整MSL时间,设置套接字选项(地址复用)
2.3.2 TCP的可靠传输:⭐
- 面向连接,连接管理
- 确认应答机制:对每一条数据,向发送方进行确认回复,
- 超时重传机制:发送数据后等待一段时间(200ms)若是没有收到确认回复,则认为数据丢失,进行重传
- 协议字段中的:序号+确认序号( 保证数据有序的 向应用层交付)
- 协议字段中的:校验和(校验接受的数据与发送的数据是否一致,不一致则发送重传请求,否则确认回复)
2.3.3 TCP提高性能的措施
TCP的缺点:
TCP为了保证可靠传输,牺牲了部分性能,(有些性能的损失是没有必要的,比如ack丢失导致的重传)
TCP又采用了几种机制来避免无畏的性能损失以及提高性能的方法:
1.滑动窗口机制:
流量控制: 通过协议字段中的窗口大小(不会大于接收方的接收缓冲区中剩余空间的大小)字段控制发送方发送的数据大小;避免因为发送过快而接受方数据处理过慢导致接收缓冲区数据放满后,大量的数据丢失重传降低的性能;
窗口大小在每次对数据进行确认回复的时候都会进行重新协商;
每一条确认回复中的确认序号,都要保证之前的数据已经全部 完全收到,没有收到第一条回复,但是收到了第二条回复,认为第一条和第二条都已经正确传输,避免因为ack丢失而导致的数据重传。
快速重传机制: 接收方收到了第二条数据,但是没有收到第一条,则初步认为第一条数据丢失,则立即发送第一条数据的重传请求,并且连续发送三次(连续三次是避免因为网络阻塞、数据延迟到达而导致的重传)
拥塞控制:
网络通信开始时,并不会直接发送窗口大小的数据,而是以一种慢启动,快增长的形式进行数据传输,起到一个网络探测的作用,避免开始通信时因为网络不好导致的发送数据越多,丢失数据越多的重传性能损失,在快增长的过程中,若出现丢包则初始化拥塞窗口大小,重新开始探测网络状况;
2.延迟应答机制:
接收方接收数据若是立即回复,则窗口大小会降低,会导致传输速度降低,因此接收方接收到数据之后,并不会立即回复,而会延迟一会(不超过500毫秒),在这期间,用户可又能将数据从接收缓冲区中取出,可以尽量大的能力保证窗口大小,保证传输速度不会降低;
3.捎带应答机制
每次接收方对发送的数据进行确认回复,若是单独发送一个数据报(仅仅包含一个tcp报头)是不划算的,解决方案就是将要进行的确认回复和将要发送的数据合到一起进行发送,就可省略一个tcp报头的发送,减少网络中不必要的流量信息;
2.3.4 面向字节流
定义: 数据不会直接发送,而是放到缓冲区中,操作系统选择一个合适的时机将合适大小的数据以字节流的形式发送出去,对方接收数据时可以一次性接收所有数据,也可以一次接受一点,分多次接受;
特性: 传输灵活,但是会造成粘包问题
粘包问题:
- tcp传输的数据在发送缓冲区或者接受缓冲区中堆积,因为tcp数据收发的灵活性,导致有可能多条数据当作一条接收;(两条数据的粘连)
- tcp粘包的本质原因:tcp在传输层,对数据的格式并不关心,对数据之间没有边界区分,因此会造成数据粘包;
- 粘包是tcp在传输层对数据边界不敏感 ,因此需要用户在应用层进行数据边界管理(tcp没解决这个问题,需要用户来处理)
用户在应用层解决粘包问题的方法:
- 特殊字符间隔
- 定长数据(耗费资源)
- 不定长数据在应用层协议头中声明数据长度
2.3.5 TCP连接中的保活机制
若是通信双方长时间没有数据往来(7200秒,即两小时),则会向对方发一个保活探测数据包,要求对方对这个数据包进行回复,若是收到回复,则连接正常,若是连续多次(9次,每次间隔75秒)没有收到回复,则认为连接断开(在Linux下输入:sysctl -a |grep keep 命令可以查看)
tcp异常连接断开的情况:
- 断电属于异常退出(关机、关闭进程属性正常关闭)
2.3.6 TCP协议字段
- 16位源/目的端口:负责端与端之间的数据传输
- 32位序号/确认序号:保证数据有序交付
- 4位头部长度解析时获取tcp头部,以4字节为单位(tcp头部最小20字节,最大60字节)
- 6位标志位:URG/ACK/PSH/RST/SYN/FIN
- 16位窗口大小:实现滑动窗口以及进行流量控制
- 16位校验和:保证数据一致性
- 16位紧急指针:带外数据
- 40字节的选项数据:可有可无
2.2 UDP协议
2.2.1 概述:
- 无连接,不可靠 :又称用户数据报协议,通信时不需要建立连接,只需要知道对端地址信息 ,就可以发送数据;并不关心对方是否收到数据和是否有序;
- 面向数据报 :数据只能一整条一整条的向应用层交付
2.2.2 UDP协议字段
16位源/目的端口 16位数据报长度 16位校验和(二进制反码求和)
16位数据报长度 (0~65535,即最大64k-8个大小):用于指定整个udp数据报的长度(包含头部)
(16位数据报长度决定了一个udp协议的数据data长度不能大于64k-8,否则发送失败)
当数据长度大于64k-8时,就需要用户在应用层进行数据分包,将数据分成一个个小于64-8大小的数据段;
udp并不保证数据有序到达, 需要用户在应用层进行包序管理;
UDP实现的应用层协议:DHCP
3. 网络层
功能:负责地址管理与路由选择
协议:IP协议
路由器
路由选择:在复杂的网络环境中,为每一条数据选择一条合适的路径
在网络中的IP地址不能随意分配,因为随意分配很容易造成IP地址冲突;
因此IP地址需要得到合理的管理才可以
一个路由器可以组件一个局域网,这时候路由器向局域网中的主机分配IP地址的时候,就必须带有自己网络的标识——网络号;这时候只需要将每个网络的网络号规范起来就可以避免IP地址冲突
在一个局域网中,路由器向主机分配IP地址,还要能够在局域网中表示这个主机,这个标识叫主机号
IP的组成:网络号+主机号
保证相邻的网络不能具有相同的网络号就可以尽可能的避免IP地址冲突
3.1网络的划分:
1. 早期 将其划分为:A、B、C、D、E类
A类:低24位是主机号,A类网络地址主机号有2^24 0.0.0.0~127.255.255.255
B类:低16位是主机号,B类网络地址主机号有65535个,128.0.0.0~191.255.255.255
C类:低八位是主机号,C类网络地址主机号有256个,192.0.0.0~223.255.255.255
2. 现在的网络划分方案:CIRD
加入了一个字段叫子网掩码,通过子网掩码来对网络进行划分
子网掩码:
由一串连续的二进制1组成的一个无符号4个字节的整数
作用:
- 子网掩码与IP地址相与能够得到网络号
- 子网掩码取反,可以得到网络中主机号的个数
例题: 现在有一个C类网络地址,将这个C类网络划分出20个子网,请问每个子网掩码是多少,IP地址范围是多少,以及各自网络的网络号是多少?
C类网络地址有256个主机,平均划分20个子网,每个子网中主机号个数是256/20
每个子网中主机号个数是12,子网掩码是连续的1,因此12取反无法得到连续的1,在每个子网主机号能少不能多的情况下,为了保证子网掩码是连续的1,因此主机号只能是8,即2^3,得到最大主机号7能少不能多的情况下
在一个网络中,并不是所有的主机号都能分配给主机:
- 主机号全为0的IP地址——网络号,用于标识一个网络
- 主机号全为1的IP地址——UDP广播地址
特殊IP地址: 127.0.0.1————本机虚拟回环网卡地址——用于本机的网络测试
在RFC1918中规定,用于组建私网的网段也不能随意使用
只有以下几个网段能够用于组建私网:10 . * . * . * 172.16 . * . * ~172.
路由选择:()
路由表:每个
3.2 IP协议字段(⭐)
- 4位版本:IPV4 / IPV6
- 4位头部长度:IP报文头最大长度60个字节(以4字节为单位)
- 8位服务类型:4位TOS字段(最小延时、最大吞吐量、最高可靠习性、最小成本),1位保留位
- 16位报文长度:限制一个IP报文最大长度64k udp数据最大长度:64k-20-8
MTU:最大传输单元
当udp数据长度,大于MTU ,小于64k-20-8时,链路层则不支持大于mtu大小数据传输,这时候网络先获取下层mtu大小,在网络层对数据进行分片
- 16位标识:udp数据有可能在网络层进行数据分片,这个标识则可以指定当前分片属于哪个udp数据包;
- 3位标志:1位启用,1位
- 13位片偏移:用于指定udp数据分片相对于udp数据包起始位置的偏移量(分片在数据包中的位置)
偏移量是以8字节为单位,所以每个分片都是8的整数倍长度(除最后一个分片) - 8位ttl:报文生命周期,最大经过的路由器跳数;
- 8位上层协议:用于数据分用时,决定由上层哪个协议进行解析(解封装)
- 16位校验和:校验数据一致性
- 32位源/目的IP地址:标识数据从哪来到哪去
- 40字节选项数据
4. 数据链路层
功能:负责相邻设备之间的数据传输;Ether;交换机
链路层协议字段:源MAC地址,目的MAC地址,上层协议类型,数据,帧尾
MAC地址:网络物理硬件地址,用于标识硬件设备
mtu对tcp协议的影响:tcp在传输层的时候就会获取mtu大小进行计算得到自己的mss大小,并于对方进行协商,取其中较小的一个作为传输大小,发送数据的时候从发送缓冲区中取出的数据大小就不会大于mss大小;tcp在传输层会自动进行数据分段,因此不会在网络层进行数据分片。
mtu对udp协议的影响:因为udp在传输层不会进行数据分段,因此当udp传输的数据大小,大于mtu但是小于64k-20-8的时候,数据会在网络层进行数据分片,分片了在对端就会进行分片重组,只要有一个分片出问题,都会导致整个udp数据报被丢弃;因此对于udp来说分片越多,传输就越危险
因此用户在应用层进行udp数据分包的时候最好就将数据大小控制在mtu-20-8
- MAC地址:这个地址的作用就是在数据链路层标识一台设备适配器的身份,MAC地址又称为硬件地址;
链路层协议
数据链路层的协议有好多种,最常用的就是以太网协议 ,该协议所使用的标准就是ETHERNET II标准 ,下图就是以太网协议标准定义的数据帧封装格式:
- 数据链路层协议有两种:
- ETHERNET II协议(现在主要使用的就是这个):
- IEEE协议