分类目录归档:技术笔记

Bullet Journal (叁)& 目标管理 | 一起来规划人生吧

本系列文章已经过半,前面讲过了什么是 Bullet Journal,如何使用 Notion,以及使用 Notion 进行财务管理的方法,文章得到了一些共鸣,这是我继续下去最大的动力。

今天就来讲讲如何使用 Notion 来做 Bullet Journal 中的目标管理部分。

IMG_20210529_082231578b995985d94aa7.jpg

目标不明确,就容易失去动力,就容易劳无所获,就容易空虚。这也许就是做个人规划的意义,确立目标,一步一步向前,让你的每一天都意义非凡。之前学习年度规划、个人使命宣言,惊叹于一个看似不可能实现的目标,在一步步细化、落实,特别是这些计划一直提醒自己要实现这个目标,多重作用之下,真的就实现了。

如果没有目标,缺少计划, 往往就只能随波逐流,跟着大部队向前,言听计从,即使是 996、007 也不敢说什么,因为如果真的离开,真的不一定就能比现在更好。计划可以给你改变的勇气,学会规划自己的人生,让自己的每一天过的都更充实,更有意义。

我使用 Notion 来做目标管理和目标分解,并利用 Notion 的各种视图做可视化,再利用强大的 Database 做筛选和看板,让目标细化到每个月,甚至每一天。还可以利用 Notion 提供的 API ,和 Trello 联动,自动标记各个事务。具体是怎么做的呢?跟我一步步看下去吧。

为了管理目标,首先创立一个 目标管理 数据库,用于目标的设立、规划及后期的监控。

该数据库内容尽量少,让自己尽可能的保持聚焦,专心完成两三个目标。比如我最近要完成自我驱动力系列(既本系列)文章的撰写,提升编码能力,并入门 API 服务器的构建。确立目标后,可以确立该目标的时间段,与下面这个数据库关联还能监控实际完成情况,让每一个目标量化。

究竟如何量化目标完成情况呢?这就需要再建立一个 任务计划 数据库,用于任务收集和目标细化。

在该数据库中添加一个项目计划字段,与前面建立的项目计划数据库关联,这样每一个任务就可以与一个具体的目标关联,在目标数据库中有公示自动计算所有任务个数及已经完成的任务个数,以此计算出目标达成度。

这样一来,每一个目标就可以分解为具体的任务,将任务完成度作为目标达成度,使得目标可量化,更容易实现。将任务计划数据库关联到每个月的 Bullet Journal 中,使用 TimeLine 视图,可以以甘特图的方式查看任务计划安排,方便安排时间,掌控自己宝贵的时间。

比如今天是 5 月 29 日,我正在进行时间线穿梭过的这件任务。在下面,可以看到任务清单。出了将任务与目标关联,也可以选择普通任务,直接收集日常进行的各种任务,还可以进行日常任务的管理。

前些阵子 Notion 的更新说明 提到了官方 API 的开放 ,并可以使用 automate.io 等平台与各种软件联动,若感兴趣可以自己进入研究,我使用该 API 与 Trello 联动,实现了目标管理的看板化,平时只需要打开 Trello 即可快速添加任务、标记任务,之后 automate.io 自动的为我同步到 Notion 中,感觉很棒!有些重复性的工作,机器比人做的出色许多!

如果需要相关的教程,请在本文下面留言,若需要我会单独写一篇教程。

以上,就是我使用 Notion 进行 Bullet Journal 目标管理部分的全部介绍了,如果文章内容对你有用我会很开心。最后,按照系列文章的承诺,给出目标管理部分的模版。

Bullet Journal & 目标管理模版:https://www.notion.so/Bullet-Journal-5fe043ef821e4090b8cb1268f9babb0e

作者:宋天伦

预告一下,下一篇文章将会介绍使用 Notion 做 Bullet Journal 日常复盘,也算是 Bullet journal 比较核心的部分了吧,尽情期待!

Bullet Journal (二)& 财务管理

Bullet Journal 是一个可以让我们生活过的更加井井有条的工具,好生活所需的一切条件之中,财务一定是逃不开的基础。上文已经介绍了 Notion 的基本使用,Bullet Journal 第二期就来讲讲如何使用 Notion 来进行财务管理吧,主要包括预算、预算监控、收支管理、投资管理以及财务分配等。

在文章的末尾,我会给出我个人使用了半年多的 Bullet Journal 财务部分,你可以很轻松的导入自己的 Notion,开箱即用。

先来讲讲预算吧,在我的 Bullet Journal 中,每个月都有一个主页,汇总了当月的目标、复盘、财务等内容,其中就包括本月的预算

预算部分没有什么技术含量,但是预算监控就不一样了。对 Budget 这一列做一个求和,得出本月预算总额,将这个内容填充入资产趋势中本月的记录中。

这条记录会与本月的账本、 时间进度联动,这样您就可以看到自己在当前这个时间进度的情况下的预算使用率了。那么如何记录自己这个月的收支状况呢?通过账本来实现。

我将账本数据库连接到每个月的主页中,根据日期筛选出本月的花销,每条记录包括描述、数额、收支渠道,以及一个标识用于哪个月预算的依赖(图中最后一列)。账本中的收支渠道资产数据库做了链接,这样根据收支记录,Notion会为你自动算出各个账户的总额。而最后一列与上面说的预算监控做了联动,在这里标记后会自动将本条记录汇总入预算使用,既可以避免一些策略转账被记入预算,又可以随时看到预算使用情况。

资产数据库除了与账本联动,还会与投资账户联动,用于自动统计扣除投资账户后的金额等信息。

投资账户中的资金状况类比于资产账户,是根据投资账本自动计算出来的,同时每一个账户可以分为保本、要花、保命、生钱等用途,投资收益也是在这里记录的,收益会自动帮您算入资产总额

投资账本数据库中,每条记录包含了你投资的备注、投资的基金以及投资的本金和时间。前面说过,最终各个投资账户的金额就是从这里汇总出来的。

至此,已经向你介绍了如何使用Notion做预算、预算监控、收支管理、投资管理,那么如何配置自己的资产呢?

在我自己进行资产配置时,参考了标准普尔家庭资产配置图的4:3:2:1法则,也就把家庭资产按4:3:2:1分别用于保本升值的钱、省钱的钱、保命的钱、要花的钱。在资产规划页面中提供了一个简单的计算器,第一行第一列根据您的记录自动算出资产总额,后面四列按照比例自动算出各用途配置的资产,而下面几条记录则是您实际花销、投资时配置的资产金额。

画一条对角线就可以看出自己当前资产配置和标准配置的差异,帮助你灵活调整。当然,这样的配置只是多种配置方法中的一种,还需要根据自身情况灵活管理。至于这个表格的实现,是通过与资产和投资账户两个数据库建立联系实现的。

至此,我使用Notion进行财务管理的方法已经介绍完毕,我也将以上内容整理出一个模版,开箱即用,帮助您快速开始资产管理。

Bullet Journal & 财务管理模版:https://www.notion.so/Bullet-Journal-db5194c3306940b3b48fea0bd02587b9

作者:宋天伦

在后续,我还会介绍使用 Notion 进行目标管理和日常管理,敬请期待哟!

拓展阅读

Bullet Journal (一) & Notion

前面介绍过 Bullet Journal 的前世今生:《Bullet Journal 的前世今生 | 效率至上(https://blog.frytea.com/archives/488/)》。近期打算写一个系列文章,主要介绍在 Notion 下进行 bullet journal 的方法和效果,包括个人财务管理、目标管理、日常管理等。

财务是一切的基础,目标是个人的方向,日常则是落实到每一天的计划和复盘。本篇文章就先来讲讲我为什么要用 Noiton 来做 Bullet Journal ,后面会给出一些效果图。分享内容只是我个人的做法,如果有自己的想法欢迎留言告诉我哟。

前文 说到“1000 个人手中应该有 1000 种子弹笔记”。而 Notion 就是这样一款极需想象力的工具软件,刚开始使用可能不知所措,深入使用会发现它有无限可能。

上图就是我个人 Bullet Journal 的主页啦,可以看到这些元素都可以随意拖拽,自由的同时支持 Markdown ,是一种有限度的自由,这样的自由往往可以发挥更大的价值。

如果想要自己用纸笔来做 Bullet Journal ,可以参考ElenaLin_青青 的 Bullet Journal排版分享,链接在文末给出。

Notion 的自由和 Bullet Journal 的多变恰好吻合,这也是 Notion 适合来做子弹笔记的原因。

除了自由的排版,Notion 提供的数据库功能强大,表格之间可以互相依赖,可以实现许多炫酷又高效的功能。

比如说在我的账本中有两个字段与其他表格建立了联系,这样在另外的表格中就可以统计出我各个账户的总额和每个月的花销啦,将每月花销和当月预算结合,就可以实时看到自己的预算使用状况,提醒自己小心花费。

除此之外,还可以很聪明的管理自己的投资账户等,详细的使用技巧,我会后面专门整理一篇文章来介绍。

基于数据库,Notion 提供了许多种试图,其中我最喜欢的就是 TimeLine 了。

这个功能用来管理自己的日常事务再好不过了,甘特图视图可以很好的看出事务执行周期,帮助自己做时间规划,近期 Notion 还开放了自己的 API ,可以和 Trello 等平台联动实现更高级的功能,若有需要还是后面再写文章详细介绍。

人类的进步离不开工具的进步,好的软件工具可以帮助当代的我们更好更高效的处理日常各种事务,此前 Notion 因为服务器在海外,功能过于强大导致运行起来有些缓慢,但前一阵子的一次更新中,软件引擎的优化使得 Notion 的运行速度得到很大的优化。

我自己在使用过程中发现 Notion 的加载速度确实快了不少,手机端更是如此。

除了用 Notion 做 Bullet Journal,还可以用它做个人博客、个人知识库、个人主页,甚至做个人 CMS ,团队协作看板等,Notion 官方提供了许多的模版,还有一些第三方的模版,如果没有方向,可以来这里寻找灵感。

如果有需要,在后续的文章中我会分享出自己的模版供您使用。

本文介绍了 Notion 来做 Bullet Journal 的种种好处,介绍了 Notion 的各种可能性,作为一款学习成本稍高的软件工具,学会它一定不会让你失望。在未来,会有越来越多好用的工具,我自己也在努力学习视图打造更有用的工具。希望未来人们不仅仅看到一个软件工具给自己带来暂时的便利或乐趣,更能够看到其背后更深层次的价值和思考。

拓展阅读

解决 Fedora 无法访问码云私有库问题

本文首发于:https://blog.frytea.com/archives/526/

近期在 Fedora 33 系统上总是无法访问 gitee 私有库,得到以下报错:

$ git clone git@gitee.com:songtianlun/workflow.git
正克隆到 'workflow'...
git@gitee.com: Permission denied (publickey).
fatal: 无法读取远程仓库。

请确认您有正确的访问权限并且仓库存在。

使用 ssh -v git@gitee.com 命令检查得到以下输出:

$ ssh -v git@gitee.com
OpenSSH_8.4p1, OpenSSL 1.1.1g FIPS  21 Apr 2020
...
debug1: send_pubkey_test: no mutual signature algorithm
...
git@gitee.com: Permission denied (publickey).

这条日志引起我的注意,搜索了一下发现有人遇到跟我一样的问题,初步判定为 Fedora 的漏洞引起,目前发现在 Fedora 33 系统与 gitee 通信会出现问题,解决方法很简单:

修改”~/.ssh/config”文件,添加如下配置(若没有该目录则新建),实测有用:

Host gitee.com
PubkeyAcceptedKeyTypes=+ssh-rsa

问题暂时得到解决,引发问题的根本原因还需要进一步探索。

参考文献

为 Windows 10 新增物理网卡子接口

本文首发于:https://blog.frytea.com/archives/525/

在进行网络设备调试时常常会使用到多 IP ,Linux 上可以很方便的为物理网卡配置子接口解决,但是在 Windows 上如果物理网卡必须使用 DHCP 就无法再配置多 IP 了,只能暂时的使用 USB 转网卡解决。近期突然灵机一动,能不能使用 Windows 10 天然支持的 WSL 来解决这个问题,经过本人实测,是可以的,方法也很简单。

环境为 Win 10 专业版,安装了 WSL Ubuntu,具体安装方法请自行百度。

安装完毕后进入 WSL, CMD 里输入 ubuntu 即可,使用 ifconfig 先看一下当前的网卡:

ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 30.30.253.241  netmask 255.255.255.240  broadcast 30.30.253.255
        inet6 fe80::5d98:1dfb:7083:f7ed  prefixlen 64  scopeid 0xfd<compat,link,site,host>
        ether 6c:4b:90:d4:a9:20  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

其中的 eth0 就是对应的 win10 物理网卡在 WSL 中的映射。

使用以下命令为该网卡配置一个子接口:

sudo ip addr add 192.168.8.123/24 dev eth0 label eth0:1

此时使用 ifconfig 看不到这个子接口,但是实际上已经生效:

可以发现在 Win10 上 ping 一个该网段 IP ,配置该子接口后立刻就通了,说明配置完成。

疑难解答

如果您配置时得到下面报错:

RTNETLINK answers: Permission denied

使用管理员权限打开 CMD,运行 ubuntuwsl ,之后再配置即可成功。(感谢 GITHUB 社区)

拓展阅读

三步激活 StarUML V4.0.1 (WIN10为例) | 仅供学习

StarUML 是一个开源的 UML 工具列表软件,它遵守 GNU GPL 的一个修订版。StarUML 项目宣称的目标是代替大型的商业 UML 工具软件,如 IBMRational RoseBorland 公司的 TogetherStarUML 支持 UML2.0 定义的大多数图,是一款跨平台且轻量高效的现代 UML 绘图工具。

但由于其商业性质,免费版仅提供一段时间的试用预览,到期后导出图片会有 未注册 字样水印,非常影响成图质量。经过一番研究,StarUML 采用 Electron 框架,使用 node.js 实现,仅需简单修改其中许可证判定代码即可完成破解,在此感谢万能的 GitHub 社区。

本教程激活 StarUML V4.0.1 ,平台为 Win10

学(ji)习(huo)步骤

第一步,解包

app.asar 文件是 Electron 程序的主业务文件,是一种压缩格式的文件。我们需要修改的部分就被压缩在这里,具体文件位置为:

C:\\Program Files\\StarUML
├─locales
├─resources
| └─app.asar
└─swiftshader

app.asar 文件可以使用编辑器直接打开,但如果直接修改会导致程序无法正常运行,因此需要解包修改再压缩。

解包前需要确认您的电脑已经安装 node.js ,可在 CMD 执行以下命令,若回显版本号说明已安装,若没有安装请移步:https://nodejs.org/en/

C:\\Program Files>node -v
v12.18.3

之后全局安装 asar 工具:

npm install -g asar
或者
cnpm install -g asar

C:\\Program Files>asar -V
v3.0.3

// 出现版本号说明安装成功

解压 app.asar 文件:

asar extract app.asar ./asar/

使用上面命令将 app.asar 解压到同级目录 asar 下,前提是 cd 到文件所在目录,并创建好 asar 文件。

2021年9月26日更新 实测 Ubuntu 20.04 下 StartUML 4.1.2 成功

$ sudo find / -name "app.asar"
/opt/StarUML/resources/app.asar

第二步,激活

解压后在 asar 目录下,找到这个文件:asar\\src\\engine\\license-manager.js,使用你偏好的编辑器打开,修改其中这段代码:

  checkLicenseValidity () {
    this.validate().then(() => {
      setStatus(this, true)
    }, () => {
      //setStatus(this,false)  <-- comment this line
      setStatus(this, true) //<-- add this line
      //UnregisteredDialog.showDialog() <-- comment this line
    })
  }

注意其中注释的部分,总结来看就是将 false 改为 true,再将 false 的后续动作注释即可。

MaxOS, Linux 类比修改,下面是我在 GitHub 找到的 v3.0.* 文件位置,待验证。。。 Mac OS: /Applications/StarUML.app/Contents/www/license/node/ Linux: /opt/staruml/www/license/node/

第三步,压缩

修改完成后,将修改后的内容重新打包回 app.asar ,使用以下命令压缩即可,其中 pack 是我前一步解压的目录:

asar pack asar app.asar

注:建议在此前备份旧的 app.asar 文件,以免造成无法挽回的损失。

若不出意外,到这里 StarUML 就已经成功激活了。

https://imagehost-cdn.frytea.com/images/2021/04/07/20210407210104e7b6dba384d8b246.png

[tip type=”info” title=”资源”] 为方便有需求的朋友,在这里直接给出我修改好的 app.aspr 及对应版本的安装包,安装好后替换 app.aspr 即可。

[file href=”https://res.frytea.com/Dev/%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/StarUML_with_aspr.zip?download”]StarUML_with_aspr.zip[/file]

若链接失效,请留言,或前往我的 资源站 查找。

[/tip]

总结

本文介绍了一种简单的直接使用官网版本激活 StarUML 的方法,避免了不明来源的破解程序对你电脑的侵害。

特别说明:本方法仅用于学习用途,请勿商用,若产生纠纷本文作者概不负责。

参考文献

Windows CMD 换肤

由于经常使用到 Windows 下的 CMD 终端进行各种操作,特别是集成了 Ubuntu 子系统之后,在 Windows 平台上进行 C 开发更方便了。为了呼出 WSL 子系统,我习惯在 CMD 下进行,可默认皮肤不够美观,为了让自己心情愉悦,检索了一番换肤方法,并在此简单记录。

环境准备

首先下载换肤工具:ColorTool

解压后在 CMD 下进入解压后的目录,运行例如以下命令即可:


C:\Users\lenovo\Downloads\ColorTool>ColorTool.exe -b schemes\OneHalfDark.itermcolors

效果预览

目录中提供了几种配色,在这里简单展示一下效果:

  • deuteranopia.itermcolors

  • OneHalfDark.itermcolors

  • OneHalfLight.itermcolors

  • solarized_dark.itermcolors

  • solarized_light.itermcolors

个人比较喜欢 OneHalfDark.itermcolors 这一款,你最喜欢哪一个呢?

参考文献

解决 Win10 热点无法上网及与 Hyper-V 虚拟网卡冲突问题

最近给 Win10 电脑加装了一个无线网卡,想要开热点使用,但是发现手机连上之后显示无法联网,在这里记录解决办法。

首先查看一下当前电脑上网使用的网卡是哪一张,我当前使用的是 Hyper-V 虚拟的一个桥接网卡 vEthernet (NetBridge) 开启 wifi 热点后新增的网卡是 本地连接* 12

现在进入上网网卡的属性,进入共享标签,发现 Internet 连接共享是关闭状态,现在将它打开,并将家庭网络连接指定为 wifi 热点的网卡,确认即可。

再次尝试连接即可。

补充:开启连接共享时报错 “无法启用 internet 连接共享,为 lan 连接配置的 ip 地址需要使用自动 ip 寻址” ,将不需要的 Vmware 虚拟网卡卸载后解决,猜测可能是占用了某些共享需要用到的网段导致。

参考文献

NMAP 基础扫描

以下几个示例带领你快速了解nmap的基本扫描方法,更多详情请查阅nmap手册。

1、Nmap 简单扫描

$ nmap <target ip address>
$ nmap 192.168.41.41

直接指定需要扫描的主机IP开始扫描,返回详细描述。

2、Nmap 扫描并输出详细信息

$ nmap <target ip address> -vv
$ nmap 192.168.41.41 -vv

3、Nmap 指定端口范围扫描

$ nmap -p(range) <target IP>
# (rangge)为要扫描的端口(范围),端口大小不能超过65535

# nmap 192.168.41.41 -p1-50
Starting Nmap 7.80 ( https://nmap.org ) at 2021-01-26 16:37 CST
Nmap scan report for bogon (192.168.41.41)
Host is up (0.0038s latency).
Not shown: 46 closed ports
PORT   STATE    SERVICE
5/tcp  filtered rje
21/tcp filtered ftp
23/tcp open     telnet
27/tcp filtered nsw-fe
MAC Address: 00:11:22:33:44:41 (Cimsys)

Nmap done: 1 IP address (1 host up) scanned in 7.99 seconds

4、Nmap 指定端口扫描

$ nmap -p(port1,port2,port3,...) <target ip> 

$ nmap -p23 192.168.41.41
Starting Nmap 7.80 ( https://nmap.org ) at 2021-01-26 16:44 CST
Nmap scan report for bogon (192.168.41.41)
Host is up (0.0083s latency).

PORT   STATE SERVICE
23/tcp open  telnet
MAC Address: 00:11:22:33:44:41 (Cimsys)

Nmap done: 1 IP address (1 host up) scanned in 0.04 seconds

5、Nmap Ping 扫描

$ nmap -sP <target ip> 
$ nmap -sP 192.168.41.41
Starting Nmap 7.80 ( https://nmap.org ) at 2021-01-26 16:45 CST
Nmap scan report for bogon (192.168.41.41)
Host is up (0.0064s latency).
MAC Address: 00:11:22:33:44:41 (Cimsys)
Nmap done: 1 IP address (1 host up) scanned in 0.02 seconds

6、Nmap路由跟踪

$ nmap --traceroute <target ip> 
$  nmap --traceroute 119.29.29.29
Starting Nmap 7.80 ( https://nmap.org ) at 2021-01-26 16:50 CST
Nmap scan report for pdns.dnspod.cn (119.29.29.29)
Host is up (0.019s latency).
Not shown: 998 filtered ports
PORT   STATE SERVICE
53/tcp open  domain
80/tcp open  http

TRACEROUTE (using port 80/tcp)
HOP RTT      ADDRESS
1   1.99 ms  bogon (192.168.6.1)
2   2.71 ms  bogon (192.168.169.9)
3   2.71 ms  bogon (192.168.169.1)
4   19.82 ms hn.kd.ny.adsl (123.14.80.1)
5   4.74 ms  hn.kd.ny.adsl (125.40.240.77)
6   6.17 ms  pc93.zz.ha.cn (61.168.37.93)
7   ... 8
9   44.19 ms no-data (125.39.198.178)
10  ... 19
20  19.46 ms pdns.dnspod.cn (119.29.29.29)

Nmap done: 1 IP address (1 host up) scanned in 10.55 seconds

7 Nmap 扫描某网段IP

$ nmap -sP <network address > </CIDR >
$ nmap -sP 192.168.8.0/24
Starting Nmap 7.80 ( https://nmap.org ) at 2021-01-26 16:53 CST
Nmap scan report for bogon (192.168.8.129)
Host is up (0.00084s latency).
Nmap done: 256 IP addresses (1 host up) scanned in 19.87 seconds

8、Nmap 探测操作系统类别

$ nmap -O <target ip> 
$  nmap -O 119.29.29.29
Starting Nmap 7.80 ( https://nmap.org ) at 2021-01-26 16:59 CST
Nmap scan report for pdns.dnspod.cn (119.29.29.29)
Host is up (0.021s latency).
Not shown: 998 filtered ports
PORT   STATE SERVICE
53/tcp open  domain
80/tcp open  http
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: specialized|media device|WAP
Running (JUST GUESSING): Linux 2.6.X|3.X (88%), Hikvision embedded (88%)
OS CPE: cpe:/o:linux:linux_kernel:2.6.10 cpe:/h:hikvision:ds-7600 cpe:/o:linux:linux_kernel:3.0 cpe:/o:linux:linux_kernel:3.10
Aggressive OS guesses: HIKVISION DS-7600 Linux Embedded NVR (Linux 2.6.10) (88%), Linux 3.0 (88%), DD-WRT v24-sp2 (Linux 3.10) (87%)
No exact OS matches for host (test conditions non-ideal).

OS detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 8.49 seconds

9、Nmap 万能扫描

此选项设置包含了1-10000的端口ping扫描,操作系统扫描,脚本扫描,路由跟踪,服务探测。 命令语法:

$ nmap -A <target ip>
$ nmap -A 119.29.29.29
Starting Nmap 7.80 ( https://nmap.org ) at 2021-01-26 17:08 CST
Nmap scan report for pdns.dnspod.cn (119.29.29.29)
Host is up (0.020s latency).
Not shown: 998 filtered ports
PORT   STATE SERVICE VERSION
53/tcp open  domain  ISC BIND 9.11.3
| dns-nsid:
|_  bind.version: 9.11.3
80/tcp open  http    Http Server
| fingerprint-strings:
|   FourOhFourRequest, GetRequest:
|     HTTP/1.0 404 Not Found
|     Connection: close
|     Server: Http Server
|     Content-Type: text/html
|     Content-Length: 174
|     
<html>
|     
<head><title>Server error message</title></head>
|     
<body>
|     
<h1>Error 404: Not Found</h1>
|     request could not be completed because:
|     Document not found!
|     </body>
|_    </html>
|_http-server-header: Http Server
|_http-title: Server error message
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port80-TCP:V=7.80%I=7%D=1/26%Time=600FDC05%P=x86_64-redhat-linux-gnu%r(
SF:GetRequest,11E,"HTTP/1\.0\x20404\x20Not\x20Found\r\nConnection:\x20clos
SF:e\r\nServer:\x20Http\x20Server\r\nContent-Type:\x20text/html\r\nContent
SF:-Length:\x20174\r\n\r\n
<html>\n<head><title>Server\x20error\x20message<
SF:/title></head>\n<body>\n<h1>Error\x20404:\x20Not\x20Found</h1>\nThe\x20
SF:request\x20could\x20not\x20be\x20completed\x20because:\n\x20Document\x2
SF:0not\x20found!\n</body>\n</html>\n")%r(FourOhFourRequest,11E,"HTTP/1\.0
SF:\x20404\x20Not\x20Found\r\nConnection:\x20close\r\nServer:\x20Http\x20S
SF:erver\r\nContent-Type:\x20text/html\r\nContent-Length:\x20174\r\n\r\n<h
SF:tml>\n
<head><title>Server\x20error\x20message</title></head>\n<body>\n<
SF:h1>Error\x20404:\x20Not\x20Found</h1>\nThe\x20request\x20could\x20not\x
SF:20be\x20completed\x20because:\n\x20Document\x20not\x20found!\n</body>\n
SF:</html>\n");
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: media device|specialized|WAP|security-misc
Running (JUST GUESSING): Linux 3.X|2.6.X (88%), Hikvision embedded (87%), Imperva SecureSphere (86%)
OS CPE: cpe:/o:linux:linux_kernel:3.0 cpe:/o:linux:linux_kernel:2.6.10 cpe:/h:hikvision:ds-7600 cpe:/o:linux:linux_kernel:3.10 cpe:/o:imperva:securesphere
Aggressive OS guesses: Linux 3.0 (88%), HIKVISION DS-7600 Linux Embedded NVR (Linux 2.6.10) (87%), DD-WRT v24-sp2 (Linux 3.10) (87%), Linux 2.6.32 (86%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 20 hops

TRACEROUTE (using port 53/tcp)
HOP RTT      ADDRESS
1   1.83 ms  bogon (192.168.6.1)
2   2.69 ms  bogon (192.168.169.9)
3   2.12 ms  bogon (192.168.169.1)
4   4.01 ms  hn.kd.ny.adsl (123.14.80.1)
5   3.74 ms  hn.kd.ny.adsl (125.40.240.77)
6   5.07 ms  pc73.zz.ha.cn (61.168.37.73)
7   ...
8   17.91 ms dns2.online.tj.cn (117.8.222.2)
9   30.42 ms no-data (125.39.198.178)
10  ... 19
20  20.12 ms pdns.dnspod.cn (119.29.29.29)

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 164.97 seconds

10、Nmap 命令混合式扫描

$ nmap -vv -p1-1000 -O <target ip>
$ nmap -vv -p1-50 -O 192.168.41.41
Starting Nmap 7.80 ( https://nmap.org ) at 2021-01-26 17:12 CST
Initiating ARP Ping Scan at 17:12
Scanning 192.168.41.41 [1 port]
Completed ARP Ping Scan at 17:12, 0.01s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 17:12
Completed Parallel DNS resolution of 1 host. at 17:12, 0.00s elapsed
Initiating SYN Stealth Scan at 17:12
Scanning bogon (192.168.41.41) [50 ports]
Discovered open port 23/tcp on 192.168.41.41
Increasing send delay for 192.168.41.41 from 0 to 5 due to 13 out of 43 dropped probes since last increase.
Completed SYN Stealth Scan at 17:12, 4.52s elapsed (50 total ports)
Initiating OS detection (try #1) against bogon (192.168.41.41)
Retrying OS detection (try #2) against bogon (192.168.41.41)
Retrying OS detection (try #3) against bogon (192.168.41.41)
Retrying OS detection (try #4) against bogon (192.168.41.41)
Retrying OS detection (try #5) against bogon (192.168.41.41)
Nmap scan report for bogon (192.168.41.41)
Host is up, received arp-response (0.0030s latency).
Scanned at 2021-01-26 17:12:37 CST for 16s

PORT   STATE    SERVICE     REASON
1/tcp  closed   tcpmux      reset ttl 64
2/tcp  filtered compressnet no-response
3/tcp  closed   compressnet reset ttl 64
4/tcp  closed   unknown     reset ttl 64
5/tcp  closed   rje         reset ttl 64
6/tcp  closed   unknown     reset ttl 64
7/tcp  closed   echo        reset ttl 64
8/tcp  closed   unknown     reset ttl 64
9/tcp  closed   discard     reset ttl 64
10/tcp closed   unknown     reset ttl 64
11/tcp closed   systat      reset ttl 64
12/tcp closed   unknown     reset ttl 64
13/tcp closed   daytime     reset ttl 64
14/tcp closed   unknown     reset ttl 64
15/tcp closed   netstat     reset ttl 64
16/tcp closed   unknown     reset ttl 64
17/tcp closed   qotd        reset ttl 64
18/tcp closed   msp         reset ttl 64
19/tcp closed   chargen     reset ttl 64
20/tcp closed   ftp-data    reset ttl 64
21/tcp closed   ftp         reset ttl 64
22/tcp closed   ssh         reset ttl 64
23/tcp open     telnet      syn-ack ttl 64
24/tcp closed   priv-mail   reset ttl 64
25/tcp closed   smtp        reset ttl 64
26/tcp closed   rsftp       reset ttl 64
27/tcp closed   nsw-fe      reset ttl 64
28/tcp closed   unknown     reset ttl 64
29/tcp closed   msg-icp     reset ttl 64
30/tcp closed   unknown     reset ttl 64
31/tcp closed   msg-auth    reset ttl 64
32/tcp closed   unknown     reset ttl 64
33/tcp closed   dsp         reset ttl 64
34/tcp closed   unknown     reset ttl 64
35/tcp closed   priv-print  reset ttl 64
36/tcp closed   unknown     reset ttl 64
37/tcp closed   time        reset ttl 64
38/tcp closed   rap         reset ttl 64
39/tcp closed   rlp         reset ttl 64
40/tcp closed   unknown     reset ttl 64
41/tcp closed   graphics    reset ttl 64
42/tcp closed   nameserver  reset ttl 64
43/tcp closed   whois       reset ttl 64
44/tcp closed   mpm-flags   reset ttl 64
45/tcp closed   mpm         reset ttl 64
46/tcp closed   mpm-snd     reset ttl 64
47/tcp closed   ni-ftp      reset ttl 64
48/tcp filtered auditd      no-response
49/tcp closed   tacacs      reset ttl 64
50/tcp closed   re-mail-ck  reset ttl 64
MAC Address: 00:11:22:33:44:41 (Cimsys)
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.80%E=4%D=1/26%OT=23%CT=1%CU=37223%PV=Y%DS=1%DC=D%G=Y%M=001122%T
OS:M=600FDD15%P=x86_64-redhat-linux-gnu)SEQ(SP=105%GCD=1%ISR=10C%TI=Z%CI=RD
OS:%TS=A)SEQ(SP=104%GCD=1%ISR=10C%TI=Z%CI=RI%II=I%TS=A)OPS(O1=M5A0ST11NW7%O
OS:2=M5A0ST11NW7%O3=M5A0NNT11NW7%O4=M5A0ST11NW7%O5=M5A0ST11NW7%O6=M5A0ST11)
OS:WIN(W1=6F90%W2=6F90%W3=6F90%W4=6F90%W5=6F90%W6=6F90)ECN(R=Y%DF=Y%T=40%W=
OS:7080%O=M5A0NNSNW7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=AS%RD=0%Q=)T2(R=Y%
OS:DF=Y%T=2B%W=80%S=A%A=Z%F=R%O=WANM109T10S%RD=0%Q=)T3(R=N)T4(R=Y%DF=Y%T=38
OS:%W=400%S=A%A=Z%F=R%O=WANM109T10S%RD=0%Q=)T5(R=Y%DF=Y%T=40%W=0%S=A%A=S+%F
OS:=AR%O=%RD=0%Q=)T5(R=N)T6(R=Y%DF=Y%T=34%W=8000%S=A%A=Z%F=R%O=WANM109T10S%
OS:RD=0%Q=)T7(R=Y%DF=N%T=26%W=FFFF%S=A%A=Z%F=R%O=WFNM109T10S%RD=0%Q=)U1(R=Y
OS:%DF=N%T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T
OS:=40%CD=S)

Uptime guess: 34.815 days (since Tue Dec 22 21:38:45 2020)
Network Distance: 1 hop
TCP Sequence Prediction: Difficulty=261 (Good luck!)
IP ID Sequence Generation: All zeros

Read data files from: /usr/bin/../share/nmap
OS detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 15.95 seconds
           Raw packets sent: 187 (12.130KB) | Rcvd: 159 (10.202KB)

参考文献

Linux 多进程通信开发之 UNIX domain Socket 通信机制从 TCP 切换为 UDP

Unix domain socket 或者 IPC socket是一种终端,可以使同一台操作系统上的两个或多个进程进行数据通信。提供 UDP 和 TCP 两种通信机制。

因为一些原因,项目现有软件架构采用的都是 IPC sockte 中的 TCP 通信机制,虽然保证了通信的可靠性,但近期需要对该程序进行热迁移(基于 criu ),有连接的 IPC 套接字状态很难被保存和恢复,而 无连接的 UDP 只需要保证服务端先冻结、先恢复即可实现程序整体状态迁移,因此写下本文,记录迁移过程,最后提供示例程序,可以自行通过 BCompare 等文本对比工具对比差异。

模式差异

至于两种通信机制的差异,除了在创建套接字时声明的差异,具体的通信流程也有差异,在这里找到 CSDN @frank909 的两张图片,感觉很有代表性,在这里引用一下。

首先是 TCP的:

https://imagehost-cdn.frytea.com/images/2021/01/13/202101131815253d04d69f377dae01.png

https://imagehost-cdn.frytea.com/images/2021/01/13/202101131815253d04d69f377dae01.png

接下来是 UDP 的:

https://imagehost-cdn.frytea.com/images/2021/01/13/2021011318145069f28463e2e1709c.png

二者的差异,主要是这几点:

  • 服务端:

(1)TCP连接在 bind() 之后需要 listen() ,而UDP不需要。

(2)TCP连接在 bind()listen() 后还需要 accept(),用来得到客户端连接描述符,而UDP不需要。

(3)收发数据,TCP使用 recv() , send() , 而 UDP 使用 recvfrom(), sendto()

(4)释放连接,TCP在客户端释放连接后需先释放 accept() 得到的客户端连接描述符,再 close(socket) ,而UDP直接 close(socket)

  • 客户端:

(1)TCP连接在bind()后需要 connect(),而UDP不需要。

(2)收发数据,TCP使用 recv() , send() , 而 UDP 使用 recvfrom(), sendto()

具体的差异可以查看下方的示例程序。

参考程序

TCP-Server

/*************************************************************************
  > File Name: ipc_tcp_server.cpp
  > Author: TianLun Song
  > Mail: songtianlun@frytea.com
  > Blog: https://blog.frytea.com
  > Created Time: Wed 13 Jan 2021 09:53:06 AM CST
 ************************************************************************/
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <memory.h>
#include <unistd.h>
#include <stdio.h>
#include 
<iostream>

using namespace std;
const char* server_file = "/tmp/ipc_tcp_server.sock";

int main(int argc,char** argv)
{
    int socket_fd = socket(AF_UNIX,SOCK_STREAM,0);
    if (socket_fd < 0)
    {
        perror("socket");
        return -1;
    }
    struct sockaddr_un addr;
    memset(&addr,0,sizeof(addr));
    addr.sun_family = AF_UNIX;
    strcpy(addr.sun_path,server_file);
    if (access(addr.sun_path,0) != -1)
    {
        remove(addr.sun_path);
    }
    if (bind(socket_fd,(sockaddr*)&addr,sizeof(addr)) < 0)
    {
        perror("bind");
        return -1;
    }
    /* --------DIFF, ipc tcp only------------ */
    if (listen(socket_fd,12) < 0)
    {
        perror("listen");
        return -1;
    }
    /* ---------------end------------ */
    struct sockaddr_un clientaddr;
    socklen_t addrlen = sizeof(clientaddr);
    char msg_buf[1024];
    /* --------DIFF, ipc tcp only------------ */
    int newcon = -1;
    newcon = accept(socket_fd,(sockaddr*)&clientaddr,&addrlen);
    if (newcon < 0)
    {
        perror("accept");
        return -1;
    }
    /* ---------------end------------ */
    while (1)
    {
        memset(msg_buf,'\0',1024);
        int rsize = recv(newcon,msg_buf,sizeof(msg_buf),0);
        if (rsize < 0)
        {
            perror("server recv error!");
            break;
        }
        cout << "I'm Unix socket(TCP) server, recv a msg:" << msg_buf << " from: " << clientaddr.sun_path << endl;
        strcpy(msg_buf, "OK,I got it!");
        int ssize = send(newcon, msg_buf, sizeof msg_buf, 0);
        if (ssize < 0)
        {
            perror("server send error!");
            break;
        }
        sleep(1);
    }
    /* --------DIFF, ipc tcp only------------ */
    if (close(newcon) < 0)
    {
        perror("close accept");
        return -1;
    }
    /* ---------------end------------ */
    if (close(socket_fd) < 0)
    {
        perror("close socket");
        return -1;
    }
    return 0;
}

TCP-Client

/*************************************************************************
  > File Name: ipc_tcp_client.cpp
  > Author: TianLun Song
  > Mail: songtianlun@frytea.com
  > Blog: https://blog.frytea.com
  > Created Time: Wed 13 Jan 2021 10:14:09 AM CST
 ************************************************************************/
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <memory.h>
#include <unistd.h>
#include <stdio.h>
#include 
<iostream>

using namespace std;

const char* server_file = "/tmp/ipc_tcp_server.sock";
const char* client_file = "/tmp/ipc_tcp_client.sock";

int main(int argc,char** argv)
{
    int socket_fd = socket(AF_UNIX,SOCK_STREAM,0);
    if (socket_fd < 0)
    {
        perror("client socket");
        return -1;
    }
    struct sockaddr_un client_addr;
    memset(&client_addr,0,sizeof(client_addr));
    client_addr.sun_family = AF_UNIX;
    strcpy(client_addr.sun_path,client_file);

    if (access(client_addr.sun_path,0) != -1)
    {
        remove(client_addr.sun_path);
    }

    if(bind(socket_fd,(sockaddr*)&client_addr,sizeof(client_addr)) < 0)
    {
        perror("client bind");
        return -1;
    }
    struct sockaddr_un serveraddr;
    memset(&serveraddr,0,sizeof(serveraddr));
    socklen_t addrlen = sizeof(serveraddr);
    serveraddr.sun_family = AF_UNIX;
    strcpy(serveraddr.sun_path,server_file);
    char msg_buf[1024];
    /* --------DIFF, ipc tcp only------------ */
    int newcon = -1;
    newcon = connect(socket_fd,(sockaddr*)&serveraddr,addrlen);
    if (newcon < 0){
        perror("client connect");
    }
    /* ---------------end------------ */
    while(1)
    {
        strcpy(msg_buf, "How are you !!!");
        int ssize = send(socket_fd, msg_buf, sizeof msg_buf, 0);
        if (ssize < 0)
        {
            perror("client send");
            continue;
        }
        int rsize = recv(socket_fd, msg_buf, sizeof(msg_buf), 0);
        if (rsize < 0)
        {
            perror("client recv");
            continue;
        }
        cout << "I'm Unix socket(TCP) client,receive a msg :" << msg_buf << endl;
        sleep(1);
    }
    if (close(socket_fd) < 0)
    {
        perror("close");
        return -1;
    }
    return 0;
}

UDP-Server

/*************************************************************************
  > File Name: ipc_udp_server.cpp
  > Author: TianLun Song
  > Mail: songtianlun@frytea.com
  > Blog: https://blog.frytea.com
  > Created Time: Wed 13 Jan 2021 09:53:06 AM CST
 ************************************************************************/
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <memory.h>
#include <unistd.h>
#include <stdio.h>
#include 
<iostream>

using namespace std;
const char* server_file = "/tmp/ipc_udp_server.sock";

int main(int argc,char** argv)
{
    int socket_fd = socket(AF_UNIX,SOCK_DGRAM,0);
    if (socket_fd < 0)
    {
        perror("socket");
        return -1;
    }
    struct sockaddr_un addr;
    memset(&addr,0,sizeof(addr));
    addr.sun_family = AF_UNIX;
    strcpy(addr.sun_path,server_file);
    if (access(addr.sun_path,0) != -1)
    {
        remove(addr.sun_path);
    }
    if (bind(socket_fd,(sockaddr*)&addr,sizeof(addr)) < 0)
    {
        perror("bind");
        return -1;
    }
    struct sockaddr_un clientaddr;
    socklen_t addrlen = sizeof(clientaddr);
    char msg_buf[1024];
    while (1)
    {
        memset(msg_buf,'\0',1024);
        int rsize = recvfrom(socket_fd,msg_buf,sizeof(msg_buf),0,(sockaddr*)&clientaddr,&addrlen);
        if (rsize < 0)
        {
            perror("server recv error!");
            break;
        }
        cout << "I'm Unix socket(UDP) server, recv a msg: " << msg_buf  << " from: " << clientaddr.sun_path << endl;
        strcpy(msg_buf, "OK,I got it!");
        int ssize = sendto(socket_fd, msg_buf, sizeof msg_buf,0,(sockaddr*)&clientaddr,addrlen);
        if (ssize < 0)
        {
            perror("server send error!");
            break;
        }
        sleep(1);
    }
    if (close(socket_fd) < 0)
    {
        perror("close socket");
        return -1;
    }
    return 0;
}

UDP-Client

/*************************************************************************
  > File Name: ipc_udp_client.cpp
  > Author: TianLun Song
  > Mail: songtianlun@frytea.com
  > Blog: https://blog.frytea.com
  > Created Time: Wed 13 Jan 2021 10:14:09 AM CST
 ************************************************************************/
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <memory.h>
#include <unistd.h>
#include <stdio.h>
#include 
<iostream>

using namespace std;

const char* server_file = "/tmp/ipc_udp_server.sock";
const char* client_file = "/tmp/ipc_udp_client.sock";

int main(int argc,char** argv)
{
    int socket_fd = socket(AF_UNIX,SOCK_DGRAM,0);
    if (socket_fd < 0)
    {
        perror("client socket");
        return -1;
    }
    struct sockaddr_un client_addr;
    memset(&client_addr,0,sizeof(client_addr));
    client_addr.sun_family = AF_UNIX;
    strcpy(client_addr.sun_path,client_file);

    if (access(client_addr.sun_path,0) != -1)
    {
        remove(client_addr.sun_path);
    }

    if(bind(socket_fd,(sockaddr*)&client_addr,sizeof(client_addr)) < 0)
    {
        perror("client bind");
        return -1;
    }
    struct sockaddr_un serveraddr;
    memset(&serveraddr,0,sizeof(serveraddr));
    socklen_t addrlen = sizeof(serveraddr);
    serveraddr.sun_family = AF_UNIX;
    strcpy(serveraddr.sun_path,server_file);
    char msg_buf[1024];
    while(1)
    {
        strcpy(msg_buf, "How are you !!!");
        int ssize = sendto(socket_fd, msg_buf, sizeof msg_buf, 0, (sockaddr*)&serveraddr,addrlen);
        if (ssize < 0)
        {
            perror("client sendto");
            continue;
        }
        int rsize = recvfrom(socket_fd, msg_buf, sizeof(msg_buf), 0,(sockaddr*)&serveraddr, &addrlen);
        if (rsize < 0)
        {
            perror("client recv");
            continue;
        }
        cout << "I'm Unix socket(TCP) client,receive a msg :" << msg_buf << endl;
        sleep(1);
    }
    if (close(socket_fd) < 0)
    {
        perror("close");
        return -1;
    }
    return 0;
}

源文件

ipc_test.zip

参考文献