从输入一个网址到浏览器页面展示到底发生了什么

2023-10-29

从输入一个网址到浏览器页面展示到底发生了什么

1. HTTP

解析URL

首先浏览器做的第一步工作就是解析URL,从而生产一个发送给服务器的请求信息。

URL是什么呢,见下图:

URL 解析

图中长长的URL实际上是请求服务器里的文件资源。

要是上图中的蓝色部分URL元素都省略可,那应该是请求哪个文件呢?

当没有路径名时,就代表访问根目录下事先设置的默认文件,也就是/index.html或者/default.html这些文件,这样就不会发生混乱了。

生成请求消息

对URL进行解析后,浏览器确定了Web服务器和文件名,接下来就是根据这些信息来生成HTTP请求消息了。

HTTP请求格式

2. DNS

通过浏览器解析URL并生成HTTP消息后,需要委托操作系统将消息发送给Web服务器,但在发送前,还有一项工作需要完成,那就是查询服务器域名对应的IP地址,因为委托操作系统发送消息时,必须提供通信对象的IP地址。

比如我们打电话的时候,必须知道对方的电话号码,但由于电话号码难以记忆,所以通常我们会将对方的电话号码+姓名保存在通讯录里。

有一种服务器专门保存了Web服务器域名IP的对应关系,它就是DNS服务器

域名解析的工作流程

  1. 客户端首先会发出一个DNS请求,问www.server.comIP是什么,并发送给本地DNS服务器(也就是客户端的TCP/IP设置中填写的DNS服务器地址)。
  2. 本地域名服务器收到客户端的请求后,如果能在缓存里的表格找到www.server.com,则直接返回IP地址。如果没有,本地DNS会去问它的根域名服务器(根域名服务器是最高层次的,它不直接解析域名,但能指明一条道路)。
  3. 根DNS收到来自本地DNS的请求后,发现后置是.com,将.com顶级域名服务器的地址告诉本地DNS。
  4. 本地DNS收到顶级域名服务器的地址后,发起请求,询问顶级域名服务器www.server.com的IP地址。
  5. 顶级域名服务器给本地DNS 负责www.server.com区域的权威DNS服务器地址。
  6. 本地DNS于是转向问权威DNS服务器www.server.com对应的IP是什么,(server.com的权威DNS服务器是域名解析结果的原出处)。
  7. 权威DNS服务器查询后将对应的IP地址x.x.x.x告诉本地DNS。
  8. 本地DNS再将IP地址返回给客户端,客户端和目标建立连接。

至此,完成了DNS的解析过程:

域名解析的工作流程

DNS域名解析的过程就像我们日常生活中找人问路的过程类似,只指路不带路

那是不是每次解析域名都要经过这么多步骤呢?

当然不是了,还有缓存这个东西。浏览器会先看自身有没有对这个域名的缓存 ,如果有,就直接返回,如果没有,就去问操作系统,操作系统也会去看自己的缓存,如果有,就直接返回,如果没有,再去hosts文件看,也没有,才会去问本地DNS服务器。

3. 协议栈

通过DNS获取到IP后,就可以把HTTP的传输工作交给操作系统中的协议栈。

协议栈分为几个部分,分别承担不同的工作。上下关系是有一定的规则的,上面的部分会向下面的部分委托工作,下面的部分收到委托的工作并执行。

img

应用程序(浏览器)通过调用Socket库,来委托协议栈工作。协议栈的上半部分有两块,分别是负责收发数据的TCP和UDP协议,这两个传输协议会接收应用层的委托执行收发数据的操作。

协议栈的下面一半是用IP协议控制网络包收发操作,在互联网上传数据时,数据会被切分成一块块的网络包,而将网络包发送给对方的操作就是由IP负责的。

IP协议中还包括ICMP协议和ARP协议:

  • ICMP协议:用于告知网络包传送过程中产生的错误信息以及各种控制信息。
  • ARP协议:根据IP地址查询相应的以太网MAC地址。

IP下面的网卡驱动程序负责控制网卡硬件,而最下面的网卡则负责完成实际的收发操作,也就是对网线中的信号执行发送和接收操作。

4. TCP

HTTP是基于TCP协议传输的,所以在这我们先了解下TCP协议。

我们先看看TCP报文头部格式:

TCP 包头格式

首先,源端口号目标端口号是必不可少的,如果没有这两个端口号,数据就不知道应该发送给哪个应用。

接下来有包的序号,这个是为了解决包乱序的问题。

还有确认号,目的是确认发出去对方是否收到,如果没有收到就重新发送,直到送达,解决丢包问题。

接下来还有一些标志位。例如 SYN是发起一个连接,ACK是回复,RST是重新连接,FIN是结束连接等。TCP是面向连接的,因而双方要维护连接的状态,这些带标志位的包的发送,会引起双方的状态变更。

还有一个重要的就是窗口大小。TCP要做流量控制,通信双方各声明一个窗口(缓存大小),标识自己当前能够处理的能力,别发送太快,处理不过来,也别发送太慢,等待时间长。

除了流量控制以外,TCP还会拥塞控制,网络通信是否阻塞,他无能为力,只能控制自己的发送速度。

TCP传输数据之前,要先三次握手建立连接,保证双方都有接收和发送的能力,具体过程见之前博客:TCP三次握手

TCP分割数据

如果HTTP请求消息比较长,超过了MSS的长度,这时TCP就需要把HTTP的数据拆解成一块块的数据发送,而不是一次性发送所有数据。

MTU 与 MSS

  • MTU:一个网络包的最大长度,以太网中一般为1500字节。
  • MSS:除去IP和TCP头部之后,一个网络包所能容纳的TCP数据的最大长度。

数据会被以MSS的长度为单位进行拆分,拆分出来的每一块数据都会被放进单独的网络包中,也就是在每个被拆分的数据加上TCP头信息,然后交给IP模块来发送数据。。

数据包分割

TCP报文生成

TCP协议会有两个端口,一个是浏览器监听的端口(通常是随机生成),一个是Web服务器监听的端口(HTTP默认端口号80,HTTPS默认端口号是443)。

在双方建立了连接之后,TCP报文中的数据部分就是存放HTTP头部+数据,组装好TCP报文后,交给下面的网络层处理,至此,网络包的报文如下:

TCP 层报文

5. IP

TCP模块在执行连接、收发、断开等各阶段操作时,都需要委托IP模块将数据封装成网络包发送给通信对象。

IP包头格式

我们先看看IP报文头部的格式:

IP 包头格式

在IP协议里面需要有源IP地址目标IP地址

  • 源IP地址,即是客户端输出的IP地址;
  • 目标IP地址,即通过DNS域名解析得到的Web服务器IP。

因为HTTP是经过TCP传输的,所以在IP包头的协议号,要填写06(十六进制),表示协议为TCP。

IP报文生成

至此,网络包的报文如下图:

IP 层报文

6. MAC

生成IP头部之后,接下来网络包还需要在IP头部的前面加上MAC头部

MAC包头格式

MAC头部是以以太网使用的头部,它包含了接收方和发送方的MAC地址等信息。

MAC 包头格式

在MAC包头里需要发送方MAC地址接收方目标MAC地址,用于两点之间的传输

一般在TCP/IP通信里,MAC包头的协议类型只使用:

  • 0800:IP协议
  • 0806:ARP协议

MAC发送方和接收方如何确认

发送方的MAC地址获取就比较简单了,MAC地址是在网卡生产时写入到ROM里的,只要将这个值读取出来写到MAC头部就可以了。

接收方的MAC地址就有点复杂了,只要告诉以太网对方的MAC地址,以太网就会帮我们把包发送过去,那么很显然这里应该填写对方的MAC地址。所以先得搞清楚应该把包发给谁,这个只要查一下路由表就知道了。在路由表中找到相匹配的条目,然后把包发送给Gateway列中的IP地址就可以了。

如何获取对方的MAC地址

不知道对方的MAC地址?不知道就喊呗。此时就需要ARP协议帮我们找到路由器的MAC地址。

ARP 广播

ARP协议会在以太网中以广播的形式,对所有以太网的设备喊出,这个IP地址是谁的?请把你的MAC地址告诉我。

然后有人就会回答,这个IP地址是我的,我的MAC地址是XXXX。

如果对方和自己处于同一个子网中,那么就能通过上面的操作得到对方的MAC地址。然后,我们将这个MAC地址写入MAC头部,MAC头部就完成了。

公网服务器的MAC地址是如何获取呢?

在发送数据包时,如果目标主机不是本地局域网,填入的MAC地址是路由器,也就是把数据包转发给路由器,路由器一直转发下一个路由器,知道转发到目标主机的路由器,发现目标IP地址是自己局域网内的主机,就会ARP请求获取目标主机的MAC地址,,从而转发到这个服务器主机。

每次都要广播获取吗?

在后续,操作系统会把本次查询结果放到一块叫做ARP缓存的内存空间留着以后用,不过缓存的时间也就几分钟,也就是说,在发包时:

  • 先查询ARP缓存,如果其中已经保存了对方的MAC地址,就不需要发送ARP查询,直接使用ARP缓存中的地址。
  • 而当ARP缓存中不存在对方的MAC地址时,则发送ARP广播查询。

至此,网络包的报文如下图:

MAC 层报文

7. 网卡

网络包只是存放在内存中的一串二进制数字信息,没有办法直接发送给对方,因此,我们需要将数字信息转换为电信号,才能在网线上传输,也就是说,这才是真正的数据发送的过程。

负责执行这一操作的是网卡,要控制网卡还需要靠网卡驱动程序。网卡驱动获取网络包之后,会将其复制到网卡内的缓存区中,接着会在其开头加上报头和起始帧分界符,在末尾加上用于检测错误的帧校验序列。

数据包

  • 起始帧分界符是一个用来表示包起始位置的标记
  • 末尾的FCS(帧校验序列)用来检查包传输过程是否有损坏

最后网卡会将包转为电信号,通过网线发送出去。

8. 交换机

下面来看一下包是如何通过交换机的。交换机的设计是将网络包原样转发到目的地,交换机工作在MAC层,也称为二层网络设备(工作于OSI模型的第2层【数据链路层】)。

交换机的包接收操作

首先,电信号到达网线接口,交换机里的模块进行接收,接下来交换机里的模块将电信号转换为数字信号。然后通过包末尾的FCS校验错误,如果没问题则放入到缓冲区。但交换机的工作方式和网卡不同,

计算机的网卡本身具有MAC地址,并通过核对接收到的包的接收方MAC地址判断是不是发给自己的,如果不是发给自己的则丢弃;相对的,交换机的端口不核对接收方MAC地址,而是直接接收所有的包并存放到缓冲区中,因此,和网卡不同,交换机的端口不具有MAC地址。

将包放入缓冲区后,接下来需要查询一下这个包的接收方MAC地址是否已经在MAC地址表中有记录了,这个MAC地址 表主要包含两个信息:

  • 一个是设备的MAC地址
  • 另一个是该设备连接在交换机的哪个端口上

交换机的 MAC 地址表

举个例子,如果收到的包的接收方 MAC 地址为 00-02-B3-1C-9C-F9,则与图中表中的第 3 行匹配,根据端口列的信息,可知这个地址位于 3 号端口上,然后就可以通过交换电路将包发送到相应的端口了。

所以,交换机根据 MAC 地址表查找 MAC 地址,然后将信号发送到相应的端口

当 MAC 地址表找不到指定的 MAC 地址会怎么样?

地址表中找不到指定的 MAC 地址。这可能是因为具有该地址的设备还没有向交换机发送过包,或者这个设备一段时间没有工作导致地址被从地址表中删除了。这种情况下,交换机无法判断应该把包转发到哪个端口,只能将包转发到除了源端口之外的所有端口上,无论该设备连接在哪个端口上都能收到这个包。这样做不会产生什么问题,因为以太网的设计本来就是将包发送到整个网络的,然后只有相应的接收者才接收包,而其他设备则会忽略这个包

此外,如果接收方 MAC 地址是一个广播地址,那么交换机会将包发送到除源端口之外的所有端口。

以下两个属于广播地址:

  • MAC 地址中的 FF:FF:FF:FF:FF:FF
  • IP 地址中的 255.255.255.255

9. 路由器

交换机与路由器的区别

网络包经过交换机之后,现在到达了路由器,并在此被转发到下一个路由器或目标设备。这一步转发的工作原理和交换机类似,也是通过查表判断包转发的目标。不过在具体的操作过程上,路由器和交换机是有区别的。

  • 因为路由器是基于 IP 设计的,俗称三层网络设备,路由器的各个端口都具有 MAC 地址和 IP 地址;
  • 交换机是基于以太网设计的,俗称二层网络设备,交换机的端口不具有 MAC 地址。

路由器基本原理

路由器的端口具有 MAC 地址,因此它就能够成为以太网的发送方和接收方;同时还具有 IP 地址,从这个意义上来说,它和计算机的网卡是一样的。当转发包时,首先路由器端口会接收发给自己的以太网包,然后路由表查询转发目标,再由相应的端口作为发送方将以太网包发送出去。

路由器的包接收操作

首先,电信号到达网线接口部分,路由器中的模块会将电信号转成数字信号,然后通过包末尾的 FCS 进行错误校验。

如果没问题则检查 MAC 头部中的接收方 MAC 地址,看看是不是发给自己的包,如果是就放到接收缓冲区中,否则就丢弃这个包。

总的来说,路由器的端口都具有 MAC 地址,只接收与自身地址匹配的包,遇到不匹配的包则直接丢弃。

查询路由表确定输出端口

完成包接收操作之后,路由器就会去掉包开头的 MAC 头部。

MAC 头部的作用就是将包送达路由器,其中的接收方 MAC 地址就是路由器端口的 MAC 地址。因此,当包到达路由器之后,MAC 头部的任务就完成了,于是 MAC 头部就会被丢弃。接下来,路由器会根据 MAC 头部后方的 IP 头部中的内容进行包的转发操作。

转发操作分为几个阶段,首先是查询路由表判断转发目标。

路由器转发

具体的工作流程根据上图,举个例子。

假设地址为 10.10.1.101 的计算机要向地址为 192.168.1.100 的服务器发送一个包,这个包先到达图中的路由器。

判断转发目标的第一步,就是根据包的接收方 IP 地址查询路由表中的目标地址栏,以找到相匹配的记录。

路由匹配和前面讲的一样,每个条目的子网掩码和 192.168.1.100 IP 做 & 与运算后,得到的结果与对应条目的目标地址进行匹配,如果匹配就会作为候选转发目标,如果不匹配就继续与下个条目进行路由匹配。

如第二条目的子网掩码 255.255.255.0192.168.1.100 IP 做 & 与运算后,得到结果是 192.168.1.0 ,这与第二条目的目标地址 192.168.1.0 匹配,该第二条目记录就会被作为转发目标。

实在找不到匹配路由时,就会选择默认路由,路由表中子网掩码为 0.0.0.0 的记录表示「默认路由」。

路由器的发送操作

接下来就会进入包的发送操作

首先,我们需要根据路由表的网关列判断对方的地址。

  • 如果网关是一个 IP 地址,则这个IP 地址就是我们要转发到的目标地址,还未抵达终点,还需继续需要路由器转发。
  • 如果网关为空,则 IP 头部中的接收方 IP 地址就是要转发到的目标地址,也是就终于找到 IP 包头里的目标地址了,说明已抵达终点

知道对方的 IP 地址之后,接下来需要通过 ARP 协议根据 IP 地址查询 MAC 地址,并将查询的结果作为接收方 MAC 地址。路由器也有 ARP 缓存,因此首先会在 ARP 缓存中查询,如果找不到则发送 ARP 查询请求。接下来是发送方 MAC 地址字段,这里填写输出端口的 MAC 地址。还有一个以太类型字段,填写 0800 (十六进制)表示 IP 协议。网络包完成后,接下来会将其转换成电信号并通过端口发送出去。这一步的工作过程和计算机也是相同的。发送出去的网络包会通过交换机到达下一个路由器。由于接收方 MAC 地址就是下一个路由器的地址,所以交换机会根据这一地址将包传输到下一个路由器。接下来,下一个路由器会将包转发给再下一个路由器,经过层层转发之后,网络包就到达了最终的目的地。

不知你发现了没有,在网络包传输的过程中,源 IP 和目标 IP 始终是不会变的,一直变化的是 MAC 地址,因为需要 MAC 地址在以太网内进行两个设备之间的包传输。

10. 服务器 与 客户端

数据包抵达了服务器,服务器肯定高兴呀,正所谓有朋自远方来,不亦乐乎?服务器高兴的不得了,于是开始扒数据包的皮!就好像你收到快递,能不兴奋吗?

网络分层模型

数据包抵达服务器后,服务器会先扒开数据包的 MAC 头部,查看是否和服务器自己的 MAC 地址符合,符合就将包收起来。

接着继续扒开数据包的 IP 头,发现 IP 地址符合,根据 IP 头中协议项,知道自己上层是 TCP 协议。

于是,扒开 TCP 的头,里面有序列号,需要看一看这个序列包是不是我想要的,如果是就放入缓存中然后返回一个 ACK,如果不是就丢弃。TCP 头部里面还有端口号, HTTP 的服务器正在监听这个端口号。

于是,服务器自然就知道是 HTTP 进程想要这个包,于是就将包发给 HTTP 进程。

服务器的 HTTP 进程看到,原来这个请求是要访问一个页面,于是就把这个网页封装在 HTTP 响应报文里。

HTTP 响应报文也需要穿上 TCP、IP、MAC 头部,不过这次是源地址是服务器 IP 地址,目的地址是客户端 IP 地址。

穿好头部衣服后,从网卡出去,交由交换机转发到路由器,路由器就把响应数据包发到了下一个路由器,就这样跳啊跳。

最后跳到了客户端的路由器,路由器扒开 IP 头部发现是想要包,于是又把包发给了交换机,再由交换机转发到客户端。

客户端收到了服务器的响应数据包后,同样也非常的高兴,客户能拆快递了!

于是,客户端开始扒皮,把收到的数据包的皮扒剩 HTTP 响应报文后,交给浏览器去渲染页面,一份特别的数据包快递,就这样显示出来了!

最后,客户端要离开了,向服务器发起了 TCP 四次挥手,至此双方的连接就断开了。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从输入一个网址到浏览器页面展示到底发生了什么 的相关文章

  • Locale.getDefault() 始终返回 en

    unix 机器上的服务器始终使用 en 作为默认区域设置 以下是区域设置输出 LANG en US LC CTYPE C LC NUMERIC C LC TIME C LC COLLATE C LC MONETARY C LC MESSAG
  • 为什么我收到的数据包数据大小大于mss?

    我在两台 PC 上使用 ifconfig ethX mtu 300 修改了 MTU 并使用 netperf 测试网络 我用 WireShark 嗅探了 SYN 数据包中的 MSS 260 但我得到了一些大于 260 的数据包 为什么 嗅探器
  • 拆分字符串以仅获取前 5 个字符

    我想去那个地点 var log src ap kernelmodule 10 001 100 但看起来我的代码必须处理 ap kernelmodule 10 002 100 ap kernelmodule 10 003 101 等 我想使用
  • Elasticsearch 无法写入日志文件

    我想激活 elasticsearch 的日志 当我运行 elasticsearch 二进制文件时 我意识到我在日志记录方面遇到问题 无法加载配置 这是输出 sudo usr share elasticsearch bin elasticse
  • 在 Linux 上更快地分叉大型进程?

    在现代 Linux 上达到与 Linux 相同效果的最快 最好的方法是什么 fork execve combo 从一个大的过程 我的问题是进程分叉大约 500MByte 大 并且一个简单的基准测试只能从进程中实现约 50 个分叉 秒 比较最
  • 抑制 makefile 中命令调用的回显?

    我为一个作业编写了一个程序 该程序应该将其输出打印到标准输出 分配规范需要创建一个 Makefile 当调用它时make run gt outputFile应该运行该程序并将输出写入一个文件 该文件的 SHA1 指纹与规范中给出的指纹相同
  • 跟踪 Linux 程序中活跃使用的内存

    我想跟踪各种程序在特定状态下接触了多少内存 例如 假设我有一个图形程序 最小化时 它可能会使用更少的内存 因为它不会重新绘制窗口 这需要读取图像和字体并执行大量库函数 这些对象仍然可以在内存中访问 但实际上并没有被使用 类似的工具top它们
  • 如何在 Linux 中编写文本模式 GUI? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 当我编写脚本 程序时 我经常想弹出一个简单的文本 gui 来提示输入 我该怎么做 例如 来自 Shel
  • 为什么 Linux perf 使用事件 l1d.replacement 来处理 x86 上的“L1 dcache misses”?

    在英特尔 x86 上 Linux用途 https stackoverflow com a 52172985 149138事件l1d replacements来实施其L1 dcache load misses event 该事件定义如下 计数
  • fopen 不返回

    我在 C 程序中使用 fopen 以只读模式 r 打开文件 但就我而言 我观察到 fopen 调用没有返回 它不返回 NULL 或有效指针 执行在 fopen 调用时被阻止 文件补丁绝对正确 我已经验证过 并且不存在与权限相关的问题 任何人
  • 如何有效截断文件头?

    大家都知道truncate file size 函数 通过截断文件尾部将文件大小更改为给定大小 但是如何做同样的事情 只截断文件的尾部和头部呢 通常 您必须重写整个文件 最简单的方法是跳过前几个字节 将其他所有内容复制到临时文件中 并在完成
  • Pyaudio 安装错误 - “命令‘gcc’失败,退出状态 1”

    我正在运行 Ubuntu 11 04 Python 2 7 1 并想安装 Pyaudio 于是我跑了 sudo easy install pyaudio 在终端中 进程退出并显示以下错误消息 Searching for pyaudio Re
  • 如何在Linux内核源代码中打印IP地址或MAC地址

    我必须通过修改 Linux 内核源代码来稍微改变 TCP 拥塞控制算法 但为了检查结果是否正确 我需要记录 MAC 或 IP 地址信息 我使用 PRINTK 函数来打印内核消息 但我感觉很难打印出主机的MAC IP地址 printk pM
  • PHP 从命令行启动 gui 程序,但 apache 不启动

    首先 我阅读了有类似问题的人的一些帖子 但所有答案都没有超出导出 DISPLAY 0 0 和 xauth cookies 这是我的问题 提前感谢您的宝贵时间 我开发了一个小库 它使用 OpenGL 和 GLSL 渲染货架 过去几天我将它包装
  • CentOS:无法安装 Chromium 浏览器

    我正在尝试在 centOS 6 i 中安装 chromium 以 root 用户身份运行以下命令 cd etc yum repos d wget http repos fedorapeople org repos spot chromium
  • os.Mkdir 和 os.MkdirAll 权限

    我正在尝试在程序开始时创建一个日志文件 我需要检查是否 log如果不创建目录 则目录存在 然后继续创建日志文件 好吧 我尝试使用os Mkdir 也os MkdirAll 但无论我在第二个参数中输入什么值 我都会得到一个没有权限的锁定文件夹
  • 如何在apache 2.4.6上安装apxs模块

    我刚刚用过apt get update我的 apache 已更新为2 4 6 我想安装 apxs 来编译模块 但收到此错误 The following packages have unmet dependencies apache2 pre
  • Linux 可执行文件与 OS X“兼容”吗?

    如果您在基于 Linux 的平台上用 C 语言编译一个程序 然后将其移植以使用 MacOS 库 它会工作吗 来自编译器的核心机器代码在 Mac 和 Linux 上兼容吗 我问这个问题的原因是因为两者都是 基于 UNIX 的 所以我认为这是真
  • 在 Linux 上使用多处理时,TKinter 窗口不会出现

    我想生成另一个进程来异步显示错误消息 同时应用程序的其余部分继续 我正在使用multiprocessingPython 2 6 中的模块来创建进程 我试图用以下命令显示窗口TKinter 这段代码在Windows上运行良好 但在Linux上
  • 有谁知道在哪里定义硬件、版本和序列号。 /proc/cpuinfo 的字段?

    我想确保我的 proc cpuinfo 是准确的 目前它输出 Hardware am335xevm Revision 0000 Serial 0000000000000000 我可以在代码中的哪里更改它以给出实际值 这取决于 Linux 的

随机推荐

  • Go语言基础入门

    文章目录 前言 安装 代理设置 开发环境 程序编写与编译 包和模块 包 package 模块 module 模块编写与使用 多模块工作区 总结 前言 Go是由谷歌支持的开源编程语言 属于编译型语言 对并发编程有较好的支持 官网页面 http
  • 毕业设计-基于 MATLAB 的图像分割算法研究及实现

    目录 前言 课题背景和意义 实现技术思路 一 MATLAB 开发环境简介 二 图像分割算法设计 MATLAB代码 实现效果图样例 最后 前言 大四是整个大学期间最忙碌的时光 一边要忙着备考或实习为毕业后面临的就业升学做准备 一边要为毕业设计
  • android manifest中activity android:configChanges 横竖屏切换,禁止重建Activity

    android configChanges Android configChanges mcc mnc locale touchscreen keyboard keyboardHidden navigation screenLayout f
  • 鼠标悬浮控制元素隐藏与显示 - css中鼠标的hover状态

    需求 当鼠标移动到一个元素A身上时 另外一个元素B显示 实现原理 A元素与B元素有一个相同的父级 B元素默认隐藏 A元素默认显示 当鼠标移动到A元素身上时 也可以看做是移动到了A元素的父级身上 A元素的父级获得一个鼠标的hover状态 cs
  • Spring+线程池:并发处理大批量数据,解决IO效率问题思路

    点击上方 Java基基 选择 设为星标 做积极的人 而不是积极废人 每天 14 00 更新文章 每天掉亿点点头发 源码精品专栏 原创 Java 2021 超神之路 很肝 中文详细注释的开源项目 RPC 框架 Dubbo 源码解析 网络应用框
  • Linux版本 串口调试助手 发布

    苦于Linux下没有类似 串口调试助手 之类的小软件 工作起来不是太方便 最终下决心写一个串口调试助手 界面就不用重新设计了 直接照着Windows下一个叫sscom的串口调试助手工具界面进行设计 非盈利 应该不涉及到版权吧 使用Qt5进行
  • 编译原理实验 实验一 词法分析设计 Java实现

    一 实验目的 通过本实验的编程实践 使学生了解词法分析的任务 掌握词法分析程序设计的原理和构造方法 使学生对编译的基本概念 原理和方法有完整的和清楚的理解 并能正确地 熟练地运用 二 实验内容 用 VC VB JAVA 语言实现对 C 语言
  • 文档ing Wazuh——Agent(未完待续)

    Wazuh由三部分组成 Agent端 Server端 ES 下图是官方给出的整体架构图 server端收集数据以日志形式加密后发送到manager 经过解码和规则匹配生成事件和告警通过filebeat采集送到ES之中 经过logstash进
  • Centos中 docker镜像启动成功 centos中和外部都无法访问项目 踩坑!!!

    异常 curl 56 Recv failure Connection reset by peer 在一次centos环境中搭建docker docker正常启动成功 镜像也运行成功 但就是在linux里面和外部都无法访问启动的项目地址 在网
  • Android 短信验证码倒计时60s实现步骤

    博主前些天发现了一个巨牛的人工智能学习网站 通俗易懂 风趣幽默 忍不住也分享一下给大家 点击跳转到网站 首先网上有很多倒计时60s的文章 但是我觉得讲的都不够详细 把自己写好的代码发出来供大家参考一下 1 我是用的Android 已经封装好
  • Vue自定义指令以及几个非常实用的自定义指令

    在 Vue 除了核心功能默认内置的指令 v model 和 v show Vue 也允许注册自定义指令 它的作用价值在于当开发人员在某些场景下需要对普通 DOM 元素进行操作 Vue 自定义指令有全局注册和局部注册两种方式 先来看看注册全局
  • cin和getline混合使用的注意事项

    1 cin cin的工作机制归结为一句话为 非空开始 空前结束 空一般指代Enter Space Tab键 注意 cin不会删除非空字符后面的缓冲区换行符 n 2 getline getline的工作机制归结为一句话为 缓冲开始 回车前结束
  • 路径追踪原理及实现

    路径追踪 Path Tracing 原理及实现 一 渲染方程 L o p w o
  • 专业技术人员继续教育考试题

    答案都是用红色标出来了 结果复制进来都没法保留颜色 只好整理成文档放我空间里 大家去下载吧 基本能保证考个75分不成问题 也就是4道题能在这里找到3道原题 https download csdn net download leva345 8
  • 2023计算机毕业设计新颖选题推荐 -计算机专业毕业设计题目参考

    最近很多同学都在问我如何选题 今天给大家简单分享下经验 功能不知道怎么定的随时与我沟通 先介绍一下自己 本人在大学毕业那年 曾经有幸协助指导老师做过毕业设计课题分类 论文初选 代码刻录等打杂的工作 也帮助过同届N多同学完成过毕设工作 毕业后
  • CreateProcess执行控制台程序,并获取输出

    void StartProcess LPCWSTR program LPCWSTR args const int MY PIPE BUFFER SIZE 1024 初始化管道 HANDLE hPipeRead HANDLE hPipeWri
  • 【iOS】如何在 NSViewController、NSView 中关闭当前 NSWindowController ?

    前言 一般来说 用户会通电点击 x 按钮来关闭 但有些场景 比如登录页需要在登录成功时关闭 这是应该怎么办呢 解决 网上一般会说这种方案 不建议使用 class BaseWindowController NSWindowController
  • GPT-2代码解读[1]:Overview和Embedding

    GPT 2代码解读 1 Overview和Embedding Abstract 随着Transformer结构给NLU和NLG任务带来的巨大进步 GPT 2也成为当前 2020 年顶尖生成模型的泛型 研究其代码对于理解Transformer
  • 【Arduino学习】04.按键点灯实验

    数字 I O 端口的含义是 INPUT 和 OUTPUT 接口 在以前的 LED 灯实验中 我们只使用 GPIO 的OUTPUT 功能 现在让我们尝试在 Arduino 中使用 I O 的 INPUT 功能 即该功能是在本实验中从外部设备读
  • 从输入一个网址到浏览器页面展示到底发生了什么

    从输入一个网址到浏览器页面展示到底发生了什么 1 HTTP 解析URL 首先浏览器做的第一步工作就是解析URL 从而生产一个发送给服务器的请求信息 URL是什么呢 见下图 图中长长的URL实际上是请求服务器里的文件资源 要是上图中的蓝色部分