大家好,欢迎来到IT知识分享网。
初识网络原理概念
IP地址和端口号
IP地址用于定位主机的网络地址。
IP 地址(IPv4 地址)由 32 位正整数来表示,IP 地址在计算机是以二进制的方式处理的。
端口号用于定位主机中的进程
注意:两个不同的进程,不能绑定同一个端口号,但一个进程可以绑定多个端口号
TCP/IP五层(或四层)模型
TCP/IP通讯协议采用了5层的层级结构,每一层都呼叫它的下一层所提供的网络来完成自己的需求。
| 应用层 | 负责应用层序间的沟通 |
|---|---|
| 传输层 | 负责两台主机之间的数据传输 |
| 网络层 | 负责地址管理和路由选择 |
| 数据链路层 | 负责设备之间的数据帧的传送和识别 |
| 物理层 | 负责光/电信号的传递方式 |
应用层协议之HTTP
HTTP基本概念
详细解释「超文本传输协议」?
从协议的角度理解HTTP:HTTP 是一个用在计算机世界里的协议。它使用计算机能够理理解的语言确立了一种计算机之间交流通信的规范(两个以上的参与者),以及相关的各种控制和错误处理方(行为约定和规范)。
从传输的角度理解HTTP:HTTP 协议是一个双向协议。在 HTTP 里,需要中间人遵从 HTTP 协议,只要不打扰基本的数据传输,就可以添加任意额外的东西。
从超文本的角度理解HTTP:HTTP 传输的内容是「超文本」。
总结:HTTP 是一个在计算机世界里专门在「两点」之间「传输」文字、图片、音频、视频等「超文本」数据的「约定和规范」。
HTTP 常见的状态码,有哪些?
常见的HTTP状态码:表示这次请求的“结果”
- 200OK:表示访问成功
- 301 Moved Permanently:永久重定向(永久重定向,旧地址被永久移除,客户端向新地址发送请求。)
- 302 Move temporarily:临时重定向(临时重定向,旧地址还在,客户端继续向旧地址发送请求。)
- 400 Bad Request :表示客户端请求的报文有错误,但只是个笼统的错误。
- 403 Forbidden:访问被拒绝(例如没有权限或者没有登录)
- 404 Not Found:没有找到资源
- 405 Method Not Allowed:服务器不支持该方法
- 500 Internal Server Error:与 400 类型,是个笼统通用的错误码,服务器器发生了什么错误,我们并不不知道。
| 具体含义 | 常见的状态码 | |
|---|---|---|
| 1×× | 提供信息,表示目前是协议处理的中间状态,还需要后续的操作 | 常见的状态码 |
| 2×× | 成功,报文已经收到并被正确处理 | 200 |
| 3×× | 重定向,资源位置发生变动,需要客户端重新发送请求 | 301,302 |
| 4×× | 客户端错误,请求报文有误,服务器无法处理 | 400,403,404 |
| 5×× | 服务器错误,服务器在处理请求时内部发生了错误 | 500 |
HTTP常见的字段有哪些?
- 首行:HTTP方法 请求的URL HTTP版本号
- 首部(请求头)header
header就是一堆键值对,键值对和键值对之间,使用换行来分割,键和值之间,使用冒号+空格来分割。
header中具体有多少行是不固定的,具体是使用一个空行来作为结束标记 - 空行
通过这个空行来表示header部分结束了。
- 正文body
有的请求有正文,有的请求没有正文。 - HTTP响应的格式
- 首行
HTTP协议版本号 状态码 状态码描述 - 协议头(header)
- 空行
- 正文
HTTP在传输层依赖TCP协议,TCP是面向字节流的,如果没有这个空行,就会出现“粘包问题”
对URL的详细分析
- 地址,域名:例如www.baidu.com
本质上是一个IP地址,写成域名是为了方便记忆。地址后面还可以带一个冒号,冒号后面可以写一个端口号,表示要访问服务器的端口,不写就代表使用默认的端口号,对于HTTP协议来说,默认的端口号是80,对于HTTPS来说,默认的端口号是443. - URL中的路径
同一个网址中的路径不同,代表要访问服务器上不同的资源。 - URL中的参数
键值对之间通过&来分割,键和值之间使用=来分割。使用?来作为起始标志。 - URL中的片段标识符 #
使用较少,通常用于定位一个HTML页面的具体位置。
URL的目的就是来区分一个网络上唯一资源
- 先通过服务器地址,定位到一个具体的服务器
- 再通过端口号定位到一个具体的应用程序
- 在通过路径定位到这个应用程序管理的一个具体资源
- 在通过查询字符串对这个具体资源的要求作出进一步的解释
- 最后通过片段标识来确定定位到这个资源的哪个部分
URL encode与decode
HTTP协议中GET和POST两个方法有什么区别?
两者没有本质区别,但在细节上还是有区别。
- 数据位置:GET把自定义数据放到query string,POST把自定义数据放到body
- 语义区别:GET一般用于“获取数据”,POST一般用于提交数据
- 幂等性:GTE请求一般会设计成“幂等”的,POST请求一般不要求设计成“幂等”【某个请求,执行一次和执行多次没有区别,如果能做到这一点,就称为“幂等”】
- 可缓存:GET请求一般会被缓存,POST请求一般不能被缓存
哪些方式会触发HTTP GET请求
- 直接在浏览器中输入URL,就会触发一个HTTP请求。
- HTML页面中的一些特殊标签,link(引入CSS),img(图片),scrip(引入JS)【加载触发】,a(超链接)【点击触发】也会触发HTTP的GET请求。
- form表单
- ajax
- 使用java代码/其他的库
- 通过Linux下的wget/curl
- 通过第三方工具,postman这类工具
通过情况下,GTE的body为空,但是可以自己构造一个body不为空的GET请求。
关于GET请求的URL长度的问题
GET的URL长度的上限以权威的RFC标准文档为准,在RFC标准文档中,HTTP协议,RFC2616标准,对于URL的长度,是没有做出限制的。
标准只是一份文件,实际开发的时候要遵守标准,但是同时也要看别人是不是严格遵守了标准。现在使用的chrome浏览器,对于URL的长度是能够支持的非常长的,一般来说不用担心长度问题。
构造POST请求的方式
- form表单
- ajax
- 第三方工具
POST请求的特点
- 首行第一部分为POST
- URL的query string一般为空,但是,也可以加上query string
- header部分有若干个键值对
- body部分一般不为空,但是,如果body为空,也是完全可行的
关于GET和POST传输数据类型
有的资料说“GET只能传输文本数据,POST可以传输二进制”(不科学),GET的query string虽然无法直接传输二进制数据,但是可以针对二进制数据进行url encode
Host键值对
一般来说是Host中的内容和URL中的地址是一致的,但是也不绝对
Content-Length
表示body的长度,单位是字节,如果没有body(GET),此时就可以没有Content-Length
Content-Type
表示body中的数据格式的类型。
- appLication/x-www-form-urlencoded:form表单提交的数据格式,此时body的格式形如
name=lisi&pass=
- multipart/form-data:form表单提交的数据格式(在form标签加上enctyped=“multipart/form-data”).通常用于提交图片/文件。body格式形如
Content-Type:multipart/form-data; boundary=---- WebKitFormBoundaryrGKCBY7qhFd3TrwA ------WebKitFormBoundaryrGKCBY7qhFd3TrwA Content-Disposition: form-data; name="text" title ------WebKitFormBoundaryrGKCBY7qhFd3TrwA Content-Disposition: form-data; name="file"; filename="chrome.png" Content-Type: image/png PNG ... content of chrome.png ... ------WebKitFormBoundaryrGKCBY7qhFd3TrwA--
- application/json:数据为json格式,body格式形如:
{
"username":"","password":"xxxx","code":"jw7l","uuid":"d110a05ccde64b16 a861fa2bddfdcd15"}
User-Agent键值对
描述了浏览器和操作系统的版本信息,形如:
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36
目前的UA已经失去了最初用于区分操作系统和浏览器版本的不同,以达到有选择性的显示图片,视频的显示问题,现在更多的用于区分PC端和移动端。
Referer键值对
表示当前页面是从哪来的,直接在浏览器中输入URL/点击收藏夹打开的页面是没有Referer。
Cookie
- Cookie是浏览器访问服务器后,服务器传给浏览器的一段数据;浏览器需要保存这段数据,不得轻易删除;此后每次浏览器访问服务器,都必须带上这段数据。
- Cookie的两个作用:第一个作用是识别用户身份,第二个作用是记录历史。
如何使用代码来构造HTTP请求
- 直接在浏览器中输入URL
- 使用form表单(可以构造GET和POST)
- 使用ajax(可以构造各种请求)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>使用ajax构造http请求</title> <!--引入第三方库jquery--> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script> </head> <body> <script> // 基于 jQuery 里面的 ajax 来进行使用 // $ 就是jquery中已经定义好的一个对象 // jquery中的所有api其实都是$对象的方法 $.ajax({
type: 'GET', url: ' http://www.baidu.com/index.html', success:function (data,status) {
// data就是响应的body,status就是响应的状态码 console.log(status); console.log(data); } }); </script> </body> </html>
ajax为了保证安全性,要求发起ajax请求的页面,和接收ajax请求的服务器,应该在同一个域名下。
如果发起请求的页面对应的域名和接收ajax请求的服务器的域名,如果两个域名不相同,就认为是一次跨域请求。
HTTP(1.1)的优点有哪些
- 简单
HTTP 基本的报文格式就是 header + body ,头部信息也是 key-value 简单文本的形式,易于理解,降低了了学习和使用的门槛。 - 灵活和易于扩展
HTTP协议里的各类请求方法、URI/URL、状态码、头字段等每个组成要求都没有被固定死,都允许开发人员自定义和扩充。
同时 HTTP 由于是工作在应用层,则它下层可以随意变化。HTTPS 也就是在 HTTP 与 TCP 层之间增加了了 SSL/TLS 安全传输层。 - 应用广泛和跨平台
HTTP协议的缺点
- 无状态双刃剑
无状态的好处,因为服务器器不不会去记忆 HTTP 的状态,所以不不需要额外的资源来记录状态信息,这能减轻服务器器的负担,能够把更更多的 CPU 和内存用来对外提供服务。
无状态的坏处,既然服务器器没有记忆能⼒力力,它在完成有关联性的操作时会非常麻烦。 - 明文传输双刃剑
- 不安全的缺点
Session和Cokkie
Cookie是HTTP协议中的一个字段。
Cookie怎么产生:是由服务器产生的,通过HTTP响应的Set-Cookie字段来进行设置
Cookie存在哪里:Cookie在浏览器(客户端)存储
Cookie怎么用:会在下次请求中自动被添加到请求中,发给服务器
Cookie存的是什么:Cookie就是一串字符串,键值对结构的字符串。
如果说Cookie是客户端的机制,那么Session就是服务器端的机制。
可以把Session简单理解为一个hash表,key就是sessionId,value就是程序员自定义的数据(里面可以存储用户的身份信息)
HTTP 与 HTTPS 有哪些区别?
- HTTP 是超文本传输协议,信息是明文传输,存在安全风险的问题。HTTPS 则解决 HTTP 不安全的缺陷,在 TCP 和 HTTP 网络层之间加入了 SSL/TLS 安全协议,使得报文能够加密传输。
- HTTP 连接建立相对简单, TCP 三次握手之后便可进行 HTTP 的报文传输。而 HTTPS 在 TCP 三
次握手之后,还需进行 SSL/TLS 的握手过程,才可进入加密报文传输。 - HTTP 的端口号是 80,HTTPS 的端口号是 443。
- HTTPS 协议需要向 CA(证书权威机构)申请数字证书,来保证服务器的身份是可信的。
HTTPS传输过程
以上传输的过程就是怎么安全的把(对称密钥)安全的传递过去,使用非对称加密中的(公钥和私钥)。
本质就是利用 非对称加密 对 对称加密的 密钥 进行加密和解密,同时引入了证书携带公钥保证了安全性。
传输层协议UDP和TCP
TCP协议的报文格式
序列号:在建立连接时由计算机生成的随机数作为其初始值,通过 SYN 包传给接收端主机,每发送一次数据,就「累加」一次该「数据字节数」的大小。用来解决网络包乱序问题。
确认应答号:指下一次「期望」收到的数据的序列号,发送端收到这个确认应答以后可以认为在这个序号以前的数据都已经被正常接收。用来解决不丢包的问题。
控制位:
- ACK:该位为 1 时,「确认应答」的字段变为有效,TCP 规定除了最初建立连接时的 SYN
包之外该位必须设置为 1 。 - RST:该位为 1 时,表示 TCP 连接中出现异常必须强制断开连接。
- SYN:该位为 1 时,表示希望建立连接,并在其「序列号」的字段进行序列号初始值的设定。
- FIN:该位为 1 时,表示今后不会再有数据发送,希望断开连接。当通信结束希望断开连接时,
通信双方的主机之间就可以相互交换 FIN 位为 1 的 TCP 段。
为什么需要 TCP 协议? TCP 工作在哪一层?
什么是TCP?
TCP 是面向连接的、可靠的、基于字节流的传输层通信协议。
- 面向连接:一定是「一对一」才能连接,不能像 UDP 协议可以一个主机同时向多个主机发送消
息,也就是一对多是无法做到的; - 可靠的:无论的网络链路中出现了怎样的链路变化,TCP 都可以保证一个报文一定能够到达接收
端; - 字节流:消息是「没有边界」的,所以无论我们消息有多大都可以进行传输。并且消息是「有序
的」,当「前一个」消息没有收到的时候,即使它先收到了后面的字节,那么也不能扔给应用层
去处理,同时对「重复」的报文会自动丢弃。 - 全双工:一个socket,既能读,也能写
什么是TCP连接?
简单来说就是,用于保证 可靠性 和 流量控制维护 的某些状态 信息,这些信息的组合,包括Socket、序列号和窗口大小称为连接。
- Socket:由 IP 地址和端口号组成
- 序列号:用来解决乱序问题等
- 窗口大小:用来做流量控制
建立一个 TCP 连接是需要客户端与服务器端达成上述三个信息的共识。
如何唯一确定一个TCP连接?
TCP四元组可以唯一确定一个连接,四元组包括如下。
- 源地址
- 源端口
- 目的地址
- 目的端口
源地址和目的地址的字段(32位)是在 IP 头部中,作用是通过 IP 协议发送报文给对方主机。
源端口和目的端口的字段(16位)是在 TCP 头部中,作用是告诉 TCP 协议应该把报文发给哪个进程。
如何在Linux系统中查看TCP状态?
保证可靠性的核心是确认应答【可靠性】
发送方法数据给接收方,接收方就回应一个应答报文。如果发送方收到了这个应答报文,那么认为是对方已经收到了。如果发送方发送了多条数据,接受方也回复了多条数据,但是网络上存在一种常见的情况:后发先至。因此不能就单纯的通过收到数据的顺序来确定逻辑,就需要对应答进行编号(报文中的序号与确认序号)。
超时重传【可靠性】
数据在传输的过程中如果发生丢包,就要进入超时重传的机制中,每次重传的等待时间会逐渐增加。
如果网络大体是正常的,那么出现连续两次甚至连续三次都丢包的概率,是非常低的。
连接管理【可靠性】
为什么要三次握手,为什么要建立连接?
- 通过三次握手的过程,来确认A和B之间的传输是通畅的,尤其是要确认,A和B各自的发送能力和接收能力是否正常。
- 协商参数,通过三次握手,让A和B之间通通气,选择一些传输中合适的参数,例如,TCP的序号从几开始。
四次握手也可以,但没有必要。两次握手不行。
三次握手过程中涉及到的一些状态转换
- LISTEN:手机开机,信号良好,随时可以打入电话
当我们创建好ServerSocket实例的时候,就进入了LISTEN状态
tcp 为什么要三次握手,两次不行吗?为什么?
因为客户端和服务端都要确认连接,①客户端请求连接服务端;②针对客户端的请求确认应答,并请求建立连接;③针对服务端的请求确认应答,建立连接;
两次无法确保A能收到B的数据;
为什么挥手需要四次?
- 关闭连接时,客户端向服务端发送 FIN 时,仅仅表示客户端不再发送数据了但是还能接收数
据。 - 服务器收到客户端的 FIN 报文时,先回一个 ACK 应答报文,而服务端可能还有数据需要处理
和发送,等服务端不再发送数据时,才发送 FIN 报文给客户端来表示同意现在关闭连接。
结束报文段:FIN
出现丢包的话,客户端就会重传FIN
如果服务器上出现大量的CLOSE_WAIT,是代码出现bug,close没有及时被调用到。
滑动窗口【效率】
在这个过程中,发送方要花很多时间来等,这个等待其实就浪费了大量的时间。
窗口大小就是指无需等待确认应答,而可以继续发送数据的最大值。如果窗口越大,整体的效率就越高。但是也不能无限大,完全不等ACK。
针对多个ACK在网络上传输的情况,如果后面的ACK先到,表示之前的数据也被对方收到了,那么之前的ACK收到或没有收到已经不重要了。
流量控制【可靠性】
对滑动窗口的进一步补充,窗口太大太小都不合适,此处流量控制室基于接收方的处理能力来限制窗口大小(接收缓冲区的剩余空间)的。
返回的ACK会把缓冲区的剩余空间发送给对方。
如果窗口为0,发送方不再发送数据,但是为了能够查询当前接收方的窗口大小,每隔一段时间,还会再来触发一个窗口探测包,通过这个包(不传输具体的业务数据)触发ACK,在这个ACK中就能够知道当前窗口的大小了。
拥塞控制【效率】
先使用一个较小的窗口来传输数据,看看是否丢包,如果不丢包,说明网络比较通畅,如果丢包,说明网络发生拥堵。
当网络通畅的时候,就逐渐加大发送速率,当网络出现丢包的问题,就立即降低发送速率。如果达到阈值,就从指数增长变成线性增长。
延时应答【效率】
在延时应答的这段时间,应用程序就会消费一部分数据,此时缓冲区的剩余空间就更大了。
捎带应答
正常情况下,服务器内核收到数据,就会立即返回ack,但是由于有了延时应答,返回的ACK不是立即返回,而是等一会,正好在这段时间,服务器要返回业务上的response了,此时就可以把这个ACK和response合二为一,把两个包变成一个包。
面向字节流【其他】
在这种面向字节流的情况下,需要注意一个重要的问题:粘包问题
应用程序从接收缓冲区读数据的时候,不知道从哪到哪是一个完整的应用层数据报。
解决办法(核心就是明确应用层数据中,包和包之间的边界)
- 给应用层数据设定“结束符”/“分隔符”
约定,每个应用层数据报一定以;结尾 - 给应用层数据设定“长度”
设定包的长度,约定每个应用层数据报的前4个字节,存储数据报的长度
异常情况【其他】
常见的异常情况:
1.进程终止
不管进程是怎么终止的,本质上都会释放对应的PCB,也会释放对应的文件描述符,一样会触发四次挥手。
“进程终止”不代表连接就终止,进程终止其实就相当于调用了socket.close()而已
如何基于UDP协议实现可靠传输?
UDP的特性
可靠/不可靠:
全双工:一个socket,既能读(socket.receive),也能写(socket.send)
几个概念:
1.端口号
端口号的用途:标识一个进程,就可以区分出当前收到的数据要交给哪个进程来处理。
进程是通过同一个网卡来传输数据的,让每个进程分别绑定不同的端口号,数据包中有一个“目的端口”字段,会根据目的端口找到对应的端口号的进程,然后把数据交给对应的进程。
实际使用的校验的算法有很多,其中比较常见的有crc(循环冗余校验)和md5校验。
TCP 和 UDP 区别
- 连接
TCP 是面向连接的传输层协议,传输数据前先要建立连接。
UDP 是不需要连接,即刻传输数据。 - 服务对象
TCP 是一对一的两点服务,即一条连接只有两个端点。
UDP 支持一对一、一对多、多对多的交互通信 - 可靠性
TCP 是可靠交付数据的,数据可以无差错、不丢失、不重复、按需到达。
UDP 是尽最大努力交付,不保证可靠交付数据。 - 拥塞控制、流量控制
TCP 有拥塞控制和流量控制机制,保证数据传输的安全性。
UDP 则没有,即使网络非常拥堵了,也不会影响 UDP 的发送速率。 - 首部开销
TCP 首部长度较长,会有一定的开销,首部在没有使用「选项」字段时是 20 个字节,如果使
用了「选项」字段则会变长的。
UDP 首部只有 8 个字节,并且是固定不变的,开销较小。 - 传输方式
TCP 是面向字节流,流式传输,没有边界,但保证顺序和可靠。
UDP 是一个包一个包的发送,是有边界的,但可能会丢包和乱序。 - 分片不同
TCP 的数据大小如果大于 MSS 大小,则会在传输层进行分片,目标主机收到后,也同样在传输
层组装 TCP 数据包,如果中途丢失了一个分片,只需要传输丢失的这个分片。
UDP 的数据大小如果大于 MTU 大小,则会在 IP 层进行分片,目标主机收到后,在 IP 层组装完
数据,接着再传给传输层,但是如果中途丢了一个分片,则就需要重传所有的数据包,这样传输
效率非常差,所以通常 UDP 的报文应该小于 MTU。
TCP和UDP应用场景
为什么 UDP 头部没有「首部长度」字段,而 TCP 头部有「首部长度」字段呢?
网络层协议之IPV4
IPv4协议:Internet网络层最核心的协议。定义了如何封装上层协议( 如UDP、 TCP) 的报文段;定义了Internet网络层寻址( IP地址) 以及如何转发IP数据报等内容。
协议头格式简单介绍
源主机为数据包设定一个生存时间,比如64,每过一个路由器就把该值减1,如果减到0就表示路由已经太长了仍然找不到目的主机的网络,就丢弃该包,因此这个生存时间的单位不是秒,而是跳(hop)。协议字段指示上层协议是TCP、UDP、ICMP还是IGMP。然后是校验和,只校验IP首部,数据的校验由更高层协议负责。IPv4的IP地址长度为32位。
IP协议核心功能
1.地址管理:能够通过一系列的规则,把网络上的设备的地址给描述出来。
2.路由选择:根据当下的源地址和目的地址,规划处一条合适的路径。
在IPV4协议,ip地址是通过32位的整数表示,通过“点分十进制”,把一个32位的数字分成4份,每一份就是8bit(一个字节),八个比特位能表示的范围是【0,255】
如何解决IP地址不能分配的问题?
1.动态分配IP
接入网络的设备分配IP地址,没接入网络的设备就不分配,但是这种方法并不能从根本上解决问题。
路由选择
这里的路由指的是IP协议中的“路径规划功能”
IP协议中,数据到达某个路由器之后,当前路由器并不知道网络整体的环境,当前路由器只是知道它附近的情况,IP协议寻路的过程,是一个“探索式”的过程。
数据链路层协议之以太网
数据链路层的作用
负责两个相邻节点之间数据的传输
核心协议
以太网(涉及到数据链路层+物理层),是一种技术标准。规定了网络拓扑结构,访问控制方式,传世速率等。
以太网的帧格式
源地址和目的地址是指网卡的硬件地址(也叫MAC地址),长度6个字节,48位,MAC地址是在出厂时固化的。
帧协议类型字段有三种值,分别对应IP,ARP,RARP
帧末尾是CRC校验码
MAC地址
通过ipconfig/all 命令查看MAC地址。
MTU
物理层存在这样的硬性限制,对应的数据链路层的数据帧,是有一定的大小范围。这个范围指标就称为MTU。
IP数据报分包,往往不是因为达到了IP的上限才分的包,而是因为达到了MTU的上限才分的包。
ARP协议
这个协议是一个“辅助性”的协议,这个协议横跨数据链路层和网络层。
作用就是根据IP查询对应的MAC地址。
工作的过程是在设备接入网络的时候,先广播一个ARP请求(当前局域网中广播),收到这个请求的设备返回ARP响应(包含了每个设备的IP和MAC)。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/105960.html














