ARP(Address Resolution Protocol)即地址解析协议, 用于实现从 IP 地址到 MAC 地址的映射,即询问目标 IP 对应的 MAC 地址。 在网络通信中,主机和主机通信的数据包需要依据OSI模型从上到下进行数据封装,当数据封装完整后,再向外发出。所以在局域网的通信中,不仅需要源目IP地址的封装,也需要源目MAC的封装。 一般情况下,上层应用程序更多关心IP地址而不关心MAC地址,所以需要通过ARP协议来获知目的主机的MAC地址,完成数据封装。 一问一答 同一个局域网里面,当PC1需要跟PC2进行通信时,此时PC1是如何处理的?
根据OSI数据封装顺序,发送方会自顶向下(从应用层到物理层)封装数据,然后发送出去,这里以PC1 ping PC2的过程举例:
PC1封装数据并且对外发送数据时,上图中出现了"failed",即数据封装失败了,为什么?
当我们令PC1去ping ip2时,此时PC1便有了通信需要的源、目的IP地址,但是PC1缺少通信需要的目的MAC地址。这就好比我们要寄一个快递,如果在快递单上仅仅写了收件人的姓名(IP),却没有写收件人的地址(MAC),那么这个快递就没法寄出,因为信息不完整,那么如何获取到PC2的MAC地址呢?
PC1和PC2进行了一次ARP请求和回复过程,通过交互,PC1便具备了PC2的MAC地址信息。在真正进行通信之前,PC1还会将PC2的MAC信息放入本地的【ARP缓存表】,表里面放置了IP和MAC地址的映射信息,例如 IP2<->MAC2。接下来,PC1再次进行数据封装,正式进入PING通信,如下:
ARP缓存表同样具有时效性,并且如果设备重启的话,这张表就会清空;也就是说,如果下次需要通信,又需要进行ARP请求。在我们的windows/macos系统下,可以通过命令行arp -a查看具体信息。s
广播请求单播回应 实际网络中,一个LAN可能有几十上百的主机:
ARP协议就需要采用以太网的"广播"功能:将请求包以广播的形式发送,交换机或WiFi设备(无线路由器)收到广播包时,会将此数据发给同一局域网的其他所有主机。
PC1发送的请求广播包同时被其他主机收到,然后PC3和PC4收到之后(发现不是问自己)则丢弃。而PC2收到之后,根据请求包里面的信息(有自己的IP地址),判断是给自己的,所以不会做丢弃动作,而是返回ARP回应包。
ARP请求是通过广播方式来实现的,那么,PC2返回ARP回应包,是否也需要通过广播来实现呢?答案是否定的。大部分网络协议在设计的时候,都需要保持极度克制,不需要的交互就砍掉,能合并的信息就合并,能不用广播就用单播,以此让带宽变得更多让网络变得更快。 ARP请求包的完整信息是:我的IP地址是IP1,MAC地址是MAC1,请问谁是PC2,你的IP2对应的MAC地址是多少?即**ARP请求首先有"自我介绍",然后才是询问**,因此PC2在收到请求之后,就可以将PC1的IP和MAC映射信息存储在本地的【ARP缓存表】,既然知道PC1在哪里,就可以返回ARP单播回应包。
ARP 数据包 ARP 请求包 ARP 响应包 ARP 协议字段解读 从功能来看,ARP协议的功能最终是获取到MAC信息,服务于链路层,ARP是链路层协议;
从层次来看,ARP协议和IP协议都基于Ethernet协议,它们在Ethernet协议里面有独立的Type类型,前者是0x0806,后者是0x0800,ARP是网络层。
ARP是解决同一个局域网上的主机或路由器的IP地址和硬件地址的映射问题,如果所要找的目标设备和源主机不在同一个局域网上。
<1> 此时主机 A 就无法解析出主机 B 的硬件地址(实际上主机 A 也不需要知道远程主机 B 的硬件地址);
<2> 此时主机A需要的是将路由器R1的IP地址解析出来,然后将该IP数据报发送给路由器R1.
<3> R1从路由表中找出下一跳路由器R2,同时使用ARP解析出R2的硬件地址。于是IP数据报按照路由器R2的硬件地址转发到路由器R2。
<4> 路由器R2在转发这个IP数据报时用类似方法解析出目的主机B的硬件地址,使IP数据报最终交付给主机B.
最初h2会通过将自己和h3的ip地址同子网掩码与运算得知:自己和h3在同一网段,可直接通信; 2.h2对数据包二层封装时,发现自己并不知道h3的mac地址,于是发送ARP广播包; 3.switch收到arp广播包后,由于没有流表,于是它向控制器发送packet_in消息; 4.控制器收到packet_in后,向switch发送packet_out,并下发流表给switch让它将数据包从除2端口以外的其他所有端口发送; 5.h3收到arp数据包后,在数据包里添加上自己的mac地址; 6.switch收到h3的arp包,由于没有流表项,于是向控制器发送packet_in消息; 7.控制器学习到h3的mac和ip地址,向switch发送packet_out消息并下发h3到h2的流表项; 8.h2知道了h3的mac地址,完成icmp包的封装,就向h3发包了; 9.由于switch没有h2->h3的流表项,所以它还是会向控制器发送packet_in; 10.控制器发送packet_out给switch并下发h2->h3的流表;至此h2和h3就能不通过控制器只通过switch直接通信啦! 合法性检查 无效情况: 源 ip 地址为全 0 或为广播、组播;源 Mac 地址为全 0 或为组播地址。
...
单播 : 发送数据到单个目的主机,每个单播报文都有一个单播 IP 地址作为目的地址 传输方式 : 是点对点传输方式 ; 弊端 : 发送者与每个接收者之间都要建立单独的数据信道 ; 广播 : 发送数据到 同一广播域或子网内所有主机 传输方式 : 是点对多点传输方式 ; 弊端 : 最后在子网中,会给无关主机发送不需要的数据 ; 组播 : 网络中某些用户需要特定数据,发送者只需要发送一次组播数据,通过组播协议,为组播数据包建立组播分发树,被传递的数据到达距离用户最近的路由器后,开始复制分发; 传输方式 : 是 点对多点 传输方式 ; 优势 : 提高了数据传送效率 ;减少了主干网拥塞的可能性 ;组播相比于单播的优势在于相同的报文在每条链路上最多有一份;组播相比于广播的优势在于组播的报文是按需发送且组播可以跨网段传输。
Git 环境搭建 安装 Git 添加 SSH key 创建 ssh key 1$ ssh-keygen -t rsa -C "cold@google.com" 克隆代码库报错,查看调试信息 1$ ssh -vv -p 29418 [git服务器IP地址] 验证 publickey 时,本地提供了私钥/home/user/.ssh/id_rsa,但是 no mutual signature algorithm 无互签名算法,尝试 ed25529 等算法但是没有匹配的认证方式。 解决办法是提供 ecdsa,ed25519,dsa 等算法的公钥和私钥对。 查看当前 OpenSSH 版本: 1$ ssh -V [git服务器IP地址] OpenSSH 8.8 考虑到cryptographically broken,开始禁用了使用SHA-1哈希算法的RSA签名算法。 这是一个客户端限制,我们必须提供能被OpenSSH 8.8认可的密钥类型,比如 OpenSSH 推荐的Ed25519。
使用 Ed25519 算法 1# 生成ed25519密钥 2$ ssh-keygen -t ed25519 -C "your_email@example.com" 3# 将私钥添加到身份验证代理 4$ ssh-add Git 拉取远程指定分支到本地 1 将远程指定分支拉取到本地指定分支上: 1$ git pull origin 远程分支名:本地分支名 将远程指定分支拉取到本地当前分支上: 1$ git pull origin 远程分支名 将与本地当前分支同名的远程分支拉取到本地当前分支上(需先关联远程分支): 1$ git pull 将本地分支与远程同名分支相关联 1$ git push -u origin 远程分支名 Git 本地推送到远程指定分支 将本地当前分支推送到远程指定分支上(注意:pull 是远程在前本地在后,push 相反): 1$ git push origin 本地分支名:远程分支名 将本地当前分支推送到与本地当前分支同名的远程分支上 1$ git push origin 本地分支名 3.
...
假设输入的数是 $m$,则其实是求一个 $ x $ 值,使其满足 $x^2 = m$,令 $f(x) = x^2 - m$ ,其实就是求方程 $f(x) = 0$ 的根。那么 $f(x)$ 的导函数是 $f’(x) = 2x$。 如果是二次函数的话,是很简单的导数运算,切线方程:$y=f′(x_n)(x−x_n)+f(x_n)$,求交点就是把 $y$ 置为零。
1package main 2 3import ( 4 "fmt" 5 "math" 6) 7 8const err float64 = 1e-8 // err 是允许的误差 9 10func Sqrt(x float64) float64 { 11 if x < 0 { 12 return -1 13 } 14 root := 1.0 15 for math.
...
环境搭建 VSCode 下载地址: https://code.visualstudio.com/
下载慢解决方法:
官网找到需要的版本后,点击下载,然后复制下载链接 将红框内地址更改为国内镜像地址 vscode.cdn.azure.cn 浏览器复制链接后重新下载 Golang 下载地址: https://golang.google.cn/dl/
VSCode 安装 Go 插件
更新 Go 工具
在更新之前需要说明的是,由于国内政策,没办法直接更新,需要代理
1# 旧版,已废弃 2go env -w GO111MODULE=on 3go env -w GOPROXY=https://goproxy.io,direct 1# 新版改成如下链接 2go env -w GO111MODULE=on 3go env -w GOPROXY=https://proxy.golang.com.cn,direct 我这里报错warning: go env -w GOPROXY=... does not override conflicting OS environment variable原因是已经有一个了,查看了环境变量是PC前主人的,手动更改了环境变量,而后关掉并重新打开 VSCode,继续下面的步骤。
在Visual Studio Code中,打开命令面板的**“帮助**>显示所有命令”。 或者使用键盘快捷方式 (Ctrl+Shift+P) Go: Install/Update tools搜索 ,然后从托盘运行命令 出现提示时,选择所有可用的 Go 工具,然后单击“确定”。 等待 Go 工具完成更新。 time time.sleep golang 的睡眠函数time.
...
GitHub Pages 实在太慢了,科学上网有时候也卡住。
搭建Git服务器 首先使用 Xshell连接服务器,并切换 root用户,回退到根路径
安装 openssh
1sudo apt-get install openssh-server # Ubuntu 2sudo yum install openssh-server # Centos 安装完成之后,查看 ssh服务是否启动
1ps -e|grep ssh 创建一个名为 git的用户,用于管理 Hexo项目
1adduser git 给 git用户添加文件的写权限
1chmod 740 /etc/sudoers 2vim /etc/sudoers 找到 User privilege specification部分,添加如下内容:
1git ALL=(ALL:ALL) ALL 按 ESC 退出编辑模式,输入 :wq保存退出
将写权限收回
1chmod 400 /etc/sudoers 切换至 git用户,创建 ~/.ssh文件夹和 ~/.ssh/authorized_keys文件,并赋予相应的权限
1su git 2mkdir ~/.ssh 3vim ~/.ssh/authorized_keys 按 i进入编辑模式,将我们先前生成的 id_rsa.pub文件中的公钥复制到 authorized_keys中,按 ESC 退出编辑模式,输入 :wq保存退出。
...
参考作者给出的教程以及官方文档twikoo和waline
通用设置 主题文件配置 在主题配置文件_config.butterfly.yml中找到comments
1comments: 2 # Up to two comments system, the first will be shown as default 3 # Choose: Disqus/Disqusjs/Livere/Gitalk/Valine/Waline/Utterances/Facebook Comments/Twikoo/Giscus/Remark42/Artalk 4 use: Twikoo,Waline 5 text: true # Display the comment name next to the button 6 # lazyload: The comment system will be load when comment element enters the browser's viewport. 7 # If you set it to true, the comment count will be invalid 8 lazyload: true 9 count: true # Display comment count in post's top_img 10 card_post_count: false # Display comment count in Home Page 在主题配置文件_config.
...
参考教程
新建source\css\twikoo.css文件,添加代码
1/* 设置文字内容 :nth-child(1)的作用是选择第几个 */ 2.el-input.el-input--small.el-input-group.el-input-group--prepend:nth-child(1):before { 3 content: "输入QQ号会自动获取昵称和头像🐧"; 4} 5 6.el-input.el-input--small.el-input-group.el-input-group--prepend:nth-child(2):before { 7 content: "收到回复将会发送到您的邮箱📧"; 8} 9 10.el-input.el-input--small.el-input-group.el-input-group--prepend:nth-child(3):before { 11 content: "可以通过昵称访问您的网站🔗"; 12} 13 14/* 当用户点击输入框时显示 */ 15.el-input.el-input--small.el-input-group.el-input-group--prepend:focus-within::before, 16.el-input.el-input--small.el-input-group.el-input-group--prepend:focus-within::after { 17 display: block; 18} 19 20/* 主内容区 */ 21.el-input.el-input--small.el-input-group.el-input-group--prepend::before { 22 /* 先隐藏起来 */ 23 display: none; 24 /* 绝对定位 */ 25 position: absolute; 26 /* 向上移动60像素 */ 27 top: -60px; 28 /* 文字强制不换行,防止left:50%导致的文字换行 */ 29 white-space: nowrap; 30 /* 圆角 */ 31 border-radius: 10px; 32 /* 距离左边50% */ 33 left: 50%; 34 /* 然后再向左边挪动自身的一半,即可实现居中 */ 35 transform: translate(-50%); 36 /* 填充 */ 37 padding: 14px 18px; 38 background: #444; 39 color: #fff; 40} 41 42/* 小角标 */ 43.
...
暂时将博客托管在了 GitHub Pages上,并将个人域名解析指向了博客,但是每次配置好 Custom domain,访问成功后,不知不觉又 404 了,查询后发现是每次 hexo deploy后,Custom domain会被重置而失效。
在项目的 source文件夹下添加一个 CNAME文件,在文件中填写自己的域名地址,注意是存放有资源的 source文件夹,而不是主题下的 source文件夹,另外 CNAME文件无后缀。 重新部署后,无需再次手动修改配置。
刚开启的PJAX就出问题了,有些JS虽然加了 data-pjax 属性,依然没有重载,出现在用户自己编写的用于计算阅读时间的js函数中。
1// 原函数写法 2aaaaaaaaaaaaaaa; 3// 现在的写法 4function pjax_reload() { 5 aaaaaaaaaaaaaaa; 6} 7document.addEventListener("pjax:complete", function () { 8 pjax_reload(); // Pjax 完成后,重新加载上面的函数 9});