wenmo8 发布的文章

Wireshark 是一款很好用的 UI 抓包工具,在 Windows、macOS 上都可以使用。最近开发的一个统计日志上报功能,发送的网络请求明明可以收到 server 正确的响应,但却捞取不到相关的日志,于是想到用 Wireshark 抓包分析内容,看看是哪里出问题了。

图中 Data 部分就是我们关心的数据包,想要进一步分析,需要将它导出为原始的二进制文件,这里一共有三种方法,下面分别说明。

方法一:直接导出

这个方法最简单有效,选中待导出的元素后,菜单选择“文件->导出分组字节流”,对应的快捷键是 Ctrl+Shift+X,从弹出的文件选择对话框中设置输出文件路径名即可。

方法二:导出为 base64

这个方法也比较直观,右键选中的元素,从菜单中选择“复制->...as a Base64 String",然后复制到文件中即可。

注意复制后的内容和 Data[...]: 后面的内容并不一致,后者其实是个 Hex Stream。

导出的数据由于是 Base64 格式,需要进一步使用 base64 命令 decode 一下:

$ cat <<"EOF" > data.base64
> LS0tLU1VTFRJLVBBUlRTLUZPUk0tREFUQS1CT1VOREFSWQ0KQ29udGVudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPSJ1c2VyZmlsZSI7IGZpbGVuYW1lPSJmaWxlIg0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0NCg0KJJQOyYGrHKk/vsnisQ24jQ91wSHUh+ucWc0pKzOpRC4qdcK8oO1Qq40po6FtYrghx/Xp68bqVqHyOgwpncrVZT9/tkd4BIFpywyL0cNhw9J9JmCuhN0gBmNdxYyCiwbld7nt96UxhveH81WlAjAZkSFdJn2MQJCd15MmjURthQ74/Ys5uoLOfTXgUolx+mMt84bwu0X4lvP8kJ8ed+SHyHTKJbgvSZn8NIkFLzShfvdum1PgvGN1H7n4LqWxOWyfeA0KLS0tLU1VTFRJLVBBUlRTLUZPUk0tREFUQS1CT1VOREFSWS0tDQo=
> EOF
$ base64 -d -i data.base64 -o data.bin
$ xxd data.bin
00000000: 2d2d 2d2d 4d55 4c54 492d 5041 5254 532d  ----MULTI-PARTS-
00000010: 464f 524d 2d44 4154 412d 424f 554e 4441  FORM-DATA-BOUNDA
00000020: 5259 0d0a 436f 6e74 656e 742d 4469 7370  RY..Content-Disp
00000030: 6f73 6974 696f 6e3a 2066 6f72 6d2d 6461  osition: form-da
00000040: 7461 3b20 6e61 6d65 3d22 7573 6572 6669  ta; name="userfi
00000050: 6c65 223b 2066 696c 656e 616d 653d 2266  le"; filename="f
00000060: 696c 6522 0d0a 436f 6e74 656e 742d 5479  ile"..Content-Ty
00000070: 7065 3a20 6170 706c 6963 6174 696f 6e2f  pe: application/
00000080: 6f63 7465 742d 7374 7265 616d 0d0a 0d0a  octet-stream....
00000090: 2494 0ec9 81ab 1ca9 3fbe c9e2 b10d b88d  $.......?.......
000000a0: 0f75 c121 d487 eb9c 59cd 292b 33a9 442e  .u.!....Y.)+3.D.
000000b0: 2a75 c2bc a0ed 50ab 8d29 a3a1 6d62 b821  *u....P..)..mb.!
000000c0: c7f5 e9eb c6ea 56a1 f23a 0c29 9dca d565  ......V..:.)...e
000000d0: 3f7f b647 7804 8169 cb0c 8bd1 c361 c3d2  ?..Gx..i.....a..
000000e0: 7d26 60ae 84dd 2006 635d c58c 828b 06e5  }&`... .c]......
000000f0: 77b9 edf7 a531 86f7 87f3 55a5 0230 1991  w....1....U..0..
00000100: 215d 267d 8c40 909d d793 268d 446d 850e  !]&}.@....&.Dm..
00000110: f8fd 8b39 ba82 ce7d 35e0 5289 71fa 632d  ...9...}5.R.q.c-
00000120: f386 f0bb 45f8 96f3 fc90 9f1e 77e4 87c8  ....E.......w...
00000130: 74ca 25b8 2f49 99fc 3489 052f 34a1 7ef7  t.%./I..4../4.~.
00000140: 6e9b 53e0 bc63 751f b9f8 2ea5 b139 6c9f  n.S..cu......9l.
00000150: 780d 0a2d 2d2d 2d4d 554c 5449 2d50 4152  x..----MULTI-PAR
00000160: 5453 2d46 4f52 4d2d 4441 5441 2d42 4f55  TS-FORM-DATA-BOU
00000170: 4e44 4152 592d 2d0d 0a

没有 base64 命令的,需要安装一下,Linux、macOS 和 windows Git Bash 均支持。
如果较老的版本不支持 -o 选项,直接重定向到输出文件即可。

通过 xxd 查看二进制数据,和 Wireshark 中右侧十六进制展示的一致。

方法三:导出为十六进制

这个方法是我最开始想到的,中间还走了一些弯路,不如上面两种方便,不过也记录一下。

右键选中的元素,从菜单中选择“复制->将字节复制为十六进制 + ASCII 转储",或者选择“...as Hex Dump” 也可,两者的区别仅在于,前者右边会多了字符区显示,与 Wireshark 元素详情中展示的更为一致。

0000   2d 2d 2d 2d 4d 55 4c 54 49 2d 50 41 52 54 53 2d   ----MULTI-PARTS-
0010   46 4f 52 4d 2d 44 41 54 41 2d 42 4f 55 4e 44 41   FORM-DATA-BOUNDA
0020   52 59 0d 0a 43 6f 6e 74 65 6e 74 2d 44 69 73 70   RY..Content-Disp
0030   6f 73 69 74 69 6f 6e 3a 20 66 6f 72 6d 2d 64 61   osition: form-da
0040   74 61 3b 20 6e 61 6d 65 3d 22 75 73 65 72 66 69   ta; name="userfi
0050   6c 65 22 3b 20 66 69 6c 65 6e 61 6d 65 3d 22 66   le"; filename="f
0060   69 6c 65 22 0d 0a 43 6f 6e 74 65 6e 74 2d 54 79   ile"..Content-Ty
0070   70 65 3a 20 61 70 70 6c 69 63 61 74 69 6f 6e 2f   pe: application/
0080   6f 63 74 65 74 2d 73 74 72 65 61 6d 0d 0a 0d 0a   octet-stream....
0090   24 94 0e c9 81 ab 1c a9 3f be c9 e2 b1 0d b8 8d   $.......?.......
00a0   0f 75 c1 21 d4 87 eb 9c 59 cd 29 2b 33 a9 44 2e   .u.!....Y.)+3.D.
00b0   2a 75 c2 bc a0 ed 50 ab 8d 29 a3 a1 6d 62 b8 21   *u....P..)..mb.!
00c0   c7 f5 e9 eb c6 ea 56 a1 f2 3a 0c 29 9d ca d5 65   ......V..:.)...e
00d0   3f 7f b6 47 78 04 81 69 cb 0c 8b d1 c3 61 c3 d2   ?..Gx..i.....a..
00e0   7d 26 60 ae 84 dd 20 06 63 5d c5 8c 82 8b 06 e5   }&`... .c]......
00f0   77 b9 ed f7 a5 31 86 f7 87 f3 55 a5 02 30 19 91   w....1....U..0..
0100   21 5d 26 7d 8c 40 90 9d d7 93 26 8d 44 6d 85 0e   !]&}.@....&.Dm..
0110   f8 fd 8b 39 ba 82 ce 7d 35 e0 52 89 71 fa 63 2d   ...9...}5.R.q.c-
0120   f3 86 f0 bb 45 f8 96 f3 fc 90 9f 1e 77 e4 87 c8   ....E.......w...
0130   74 ca 25 b8 2f 49 99 fc 34 89 05 2f 34 a1 7e f7   t.%./I..4../4.~.
0140   6e 9b 53 e0 bc 63 75 1f b9 f8 2e a5 b1 39 6c 9f   n.S..cu......9l.
0150   78 0d 0a 2d 2d 2d 2d 4d 55 4c 54 49 2d 50 41 52   x..----MULTI-PAR
0160   54 53 2d 46 4f 52 4d 2d 44 41 54 41 2d 42 4f 55   TS-FORM-DATA-BOU
0170   4e 44 41 52 59 2d 2d 0d 0a                        NDARY--..

这种格式与 xxd 显示的二进制数据形式非常类似,也是由地址部分、十六进制数据部分、字符部分组成,但是用 xxd 直接进行反向转换,却得不到想要的结果:

仔细对比两者,发现格式还是有一些细微的差别,主要表现在以下几点:

  • xxd 地址部分有 8 位,导出的仅有 4 位
  • xxd 地址部分与数据有冒号隔开,导出的没有
  • xxd 数据部分是 2 个字节一组,导出的是一个字节一组
  • xxd 地址和数据之间的空格仅一个、数据与字符之间的空格仅有两个,导出的有三个

经过一番测试,发现导致转换失败的原因仅有两个:冒号和随后的两个空格,因此需要对导出的数据进行一番修改:将地址与数据部分的三个空格,改为一个冒号加一个空格的形式。

行数少的情况可以用 vim 一直 j 到底,多的话就直接 G 到底,这点难不倒 vimer。

当然了,也可以直接用 sed 做替换:

sed -i 's/   /: /' data.xxd

没有添加 g,是因为后面三个空格不想替换。修改好之后,再用 xxd 就正常了:

$ xxd -r data.xxd
----MULTI-PARTS-FORM-DATA-BOUNDARY
Content-Disposition: form-data; name="userfile"; filename="file"
Content-Type: application/octet-stream

��u�!ԇ�Y�)+3�D.*u¼��P��)��mb�!������V��:
                                        )���e?�Gx�i�
                                                     ���a��}&`��� c]Ō���w���1���U�0�!]&}�@��ד&�Dm���9���}5�R�q�c-��E���w��t�%�/I��4�/4�~�n�S�cu��.��9l�x
----MULTI-PARTS-FORM-DATA-BOUNDARY--

有些 vimer 习惯在 vim 里搞定一切,这一步也可以在 vim 里做:

不过这里需要使用 vim -b 以二进制方式打开文件,否则可能得不到正确的结果。

总结

以上就是三种导出 Wireshark 网络包二进制数据的方法。

删除 formed data 头和尾等明文信息,我就能进行解密、解压等操作了!最终顺利的定位到了数据发送失败的原因。

年底了,水一篇不过分吧,祝各位牛马,都能顺利拿到年终奖,以及在即将到来的 2025,保住自己的饭碗,哈哈~

在UML中,多重性是指一个条目潜在的数量范围。多重性可被用于属性、操作参数、关联关系。UML元模型也使用多重性对元模型元素之间的关系进行约束。多重性总是包含基数值,它是相关条目在现实世界中的确切数量。本文将说明类属性和类操作参数的多重性。
一、属性的多重性
假设我们需要定义一个表示书的Book类,它包含有一系列的属性。我们只选取其中的书名(title)、作者(author)、页数(pages)少数几个属性进行多重性研究说明。在此前提下,Book的相关属性用类图表示如下:

在上图中,书的作者(author)是一个人,但在现实世界中,一本书的作者可能不止一人。为了能让Book类的定义适应大多数情况,我们可以考虑将作者增加到三人,这三名作者分别用属性author1、author2、author3表示,修改后的类图如下:

不过,上述设计还是存在一些潜在的问题,下面分别讨论。
首先,一本书的作者数量的限制(上述设计中的3个)是否合理?一些论文期刊允许最多3~5名作者,而许多书的作者则比3个更多,在科学研究领域,一些论文(有些论文本足以作为一本书)的作者超过了3500人。显然3500个作者的情况并不多见,但为了能够实例化作者众多的书籍,必须增加更多的作者属性。但多少个作者是合适的,这是一个难以确定的问题。
其次,定义数量庞大的作者属性而被实例化的书的作者又很少时,由于无法约束必须将作者挨个存储在排在前面的属性中,我们将不得不检查所有的作者属性,显然它的代码实现将是笨重低效的。
最后,可以使用循环简化处理众多的作者属性吗?由于这些属性的名称不同(虽然只是后缀不同,但它们是不同的属性名),对这种名称的循环在大多数编程语言中实现是困难的。
UML为上述问题提供的解决方案是指定属性的多重性,即可通过标记说明作者(author属性)的多重性表达这个属性可以存储多个值。采用多重性的Book类图如下:

在上图中可以看到,属性author在其类型Person后增加“[1..*]”说明,“[1..*]”定义了属性author的多重性,它表明属性author的值可以从1个到无限多个,或者说属性author至少有一个值。多重性使用中括号“[]”说明其允许的数量,在“[1..*]”中,1是下限,*是上限,中间的两个点表示省略的中间值,而*代表无限大,因此在这个类图中,属性author中可存储作者的数量是从1个到无限个,即属性author存储作者的数量没有限制。使用中括号“[]”说明多重性时,上限必须大于等于下限。
通常一本书至少有一名作者,而在某些特殊情况下,书的作者信息可能丢失了(佚名),或者某些电子书的作者故意不留下自己姓名,此时author这个属性的多重性就应当设定为“[0..*]”,表示有零个或者多个作者,修改后的类图如下:

在多重性为“[0..*]”时,因为其值最少可以为零,最多没有限制,表明该属性是一个可选的属性,又是一个可以有多重值的属性。在这种情况下,可以仅使用“*”更简单地表示,即“[*]”。按这种方式表达的类图如下:

了解了属性author的多重性以后,或许有人认为属性pages也应当被指定多重性。pages表示一本书的页数,书的页数确实也是一个范围内的数值,但是对于确定的一本书而言,作者可能有多个,而它的页数却是确定的一个数值。因此属性pages不具备多重值。如果您的意图是限制一本书页数所允许的范围,可以使用约束(constraint)进行指定。
同理,表示书名的属性title也不具备多重性。不过,在UML中,也允许我们使用多重性的表示方法明确指明一个属性仅有一个值。其表示方法是将多重性的上下限均指定为1,即“[1..1]”或“[1]”,故类Book的类图可修改如下,属性title和pages分别使用了上述两种形式限定其值仅有一个。

在UML中,多重性的默认值是“[1]”,即如果一个属性不指定多重性则表明该属性应当有且仅有一个值。因此,上面的两个图是等价的。所以,如果一个属性的值是可选的,即它的值可为0个或1个,此时需要明确标明其多重性,即“[0..1]”。例如一本书交由出版社正式出版时,会有一名编辑负责该书的编辑与审校,而一本书如果是电子书,则可能由作者直接发布而没有编辑。我们为Book类增加属性编辑(editor)时,同时使用多重性“[0..1]”表明其是可选的。修改后的类图如下:

在上图中,我们同时表明了属性pages的约束,约束使用大括号“{}”进行说明,它可以在属性中内嵌说明,也可以在类图中使用一个单独的区块说明,或者也可以在类图的注释中说明。上图采用内嵌说明的方式指定了属性pages的约束。
多重性与约束可同时指定,不过一些UML工具对使用内嵌方式指定这两者支持不足(主要是不支持内嵌方式的约束),此时可将约束放在类图的注释中进行说明。例如同时标明属性pages的多重性及约束时,可使用下图表示:

二、操作参数的多重性
我们也可将多重性应用于操作参数,其用法与在属性上应用相同。当然,如果一个参数的多重性为“[1]”时,我们通常省略不标记。
例如在下图中,类Ride中有一个设定骑行日程的schedule操作,它包含标明多重性的三个参数:参数for的多重性为“[1..*]”,表示参与骑行的骑手至少有一个;参数itinerary的多重性为“[2..*]”,表示路线至少有两个点(起点与终点,还可包含若干途经点);参数isSharedRide的多重性为“[0..1]”,表示它是一个可选参数,即该骑行日程是否可分享,通常一个参数如果是可选参数,应为其指定缺省值。

类图Marriage是另外一个例子,不同于上述示例中各参数多重值个数不定,其操作wed中前三个参数都有严格限定的值的个数。

多重性还可应用于其他一些行为元素中,其用法大抵一致,使用时可以举一反三,本文不再赘述。

本文分享自华为云社区
《【华为云Stack】【大架光临】第19期:混合云网络过于复杂?ENS给你全局一张网的极致体验》
,作者:华为云Stack ENS研发团队。

政企IT的混合形态

经过几十年的发展,支撑企业IT系统的数据中心已不再是单一的资源池、单一位置分布或单一平台类型,而是形成了包括多种资源池、分布在不同物理位置的混合形态。考虑到业务安全隔离、防止锁定、可靠性、技术创新、组织流程和竞标合规等因素,企业的业务系统通常会部署在不同平台的资源池和地理位置上。

随着业务的发展和技术的发展,企业应用架构不断演进,从传统单体架构,到SOA架构,然后到微服务架构,再到云原生技术的使用,应用的资源类型和架构类型也也呈现出多种形态混合共存。

面向多平台类型、多地理位置、多计算类型、多应用架构等混合多态的客户环境,网络如何提供更佳的连接服务是ENS(Enterprise Networking Service)致力解决的问题。

混合形态让网络复杂度指数级增加

经过对数百个政企客户CIO、IT主管、网络主管、网络安全主管做了调研,我们总结出政企客户IT系统混合多云多池、混合应用架构形态下的几大网络痛点问题:

  • 网络互通难

  1. 易出错:多资源池网络形成孤岛,无法集中统一管控和自动打通,网络配置管理依赖人工,跨站点网络互通复杂、低效,人工配置容易出错,且难以排查故障。

  2. 通用性差:不同资源池和云内的网络功能有些差异,模型也各有不同,网络设计规划难以在各个资源池内通用。

  • 网络安全策略管理难

  1. 策略割裂:跨站点安全策略复杂且不联动,易出现安全漏洞。

  2. 管理成本高:不同资源池的安全功能类似,但学习、配置成本和复杂度高。

  3. 迁移难:跨站点业务负载迁移需要IP变更,需重新配置网络和安全策略,迁移困难。

  • 应用连接体验差

  1. 传统应用和云原生应用之间互访、不同k8s集群之间的应用互访,是分段式网络配置管理,缺少统一操作体验。

  2. 缺少服务统一管理、精细化的服务治理。

  • 网络运维效率低

  1. 网络与应用问题定界定位难:业务受损时,难以快速确定问题来源于哪个资源池,以及是网络问题还是应用问题。

  2. 虚拟网络与物理网络定界定位难:业务受损时,无法迅速判断是虚拟网络问题还是物理网络问题,或确定涉及的资源池。

  3. 缺乏事故现场记录与定界手段:偶发问题无历史记录,难以抓取事故现场证据并进行有效定位。。

  • 资源迁移难

多资源池的网络不能自动打通,导致分散在不同资源池的资源不能调度和迁移,且弹性不足。

总结来说,政企客户IT系统混合形态下的网络痛点问题主要包括网络连接难、应用连接难、网络安全管理难、运维定界难等问题,解决这些痛点问题,需要一个立足全局视角的全新服务模型和架构来支撑,这是华为云Stack ENS服务产生的背景。

华为云Stack面向混合网络的探索

华为云Stack 致力于为客户提供在混合平台和混合应用环境下“一朵云”的能力和体验。我们全新开发的网络服务,支持覆盖传统IT/虚拟化资源池、华为云Stack各版本资源池、华为云资源池以及异构云资源池。在此基础上,该服务提供统一连接、统一安全和统一运维三大核心功能:

  • 统一连接配置
    :跨池跨云便捷、高效、安全、可靠、一致操作体验的网络和应用连接。

  • 统一安全策略
    :跨池跨云一致的网络安全策略,覆盖云内、云间、云边的具备防御纵深的立体式安全防护。

  • 统一运维能力
    :跨池跨云可视化监控,覆盖物理网络基础设施、虚拟网络基础设施、业务应用的一体化运维。

解决混合多池的网络问题后,可以进一步与算力协同,实现跨资源池的业务部署、迁移、扩容和容灾。无论资源池内部署的是传统应用还是云原生应用,都能突破资源池边界,实现自动互通。

华为云Stack ENS服务,混合多云多池网络自动连接,为客户提供一张网体验

ENS 面向混合多态的客户环境,支持多平台类型、多地理位置、多计算类型和多应用架构,提供跨云跨池的高速网络连接和一致的安全策略自动化服务。通过集中管控、自动连通、高效安全和可视化运维,ENS 实现两类连接功能:1. 资源连接聚焦跨池跨云的IP互联;2. 应用连接聚焦跨集群跨云跨池的服务互联。

ENS面向资源的多云多池网络连接

资源网络连接旨在实现跨云跨池的网络互通和网络安全服务化,网络互通包括基础的二三层互通和增强的广域网协同、WAN侧协同;网络安全包括近端安全、跨域安全,以及安全-资源联动:

  1. 跨域互联互通:提供云平台无关的跨云跨池通用声明式网络,屏蔽平台网络模型差异;跨云跨池网络互通统一管控、自动化;既支持跨华为云Stack不同版本资源池、虚拟化资源池、华为云之间的三层互通,也支持二层互通。

  2. 可视化监控:网络拓扑可视化,流量监控统计,流量路径可视化。

  3. 跨域网络安全:提供云平台无关的跨云跨池通用安全模型,屏蔽平台安全模型差异;跨云跨池的计算近端和边界安全统一管控,策略自动化。

  4. 跨域数据迁移:跨华为云Stack不同版本资源池、虚拟化资源池、华为云的业务迁移,网络配置和安全策略自动跟随,流量就近出口。

  5. 云网协同:广域网控制器集成协同,包括流量标签,流量分类,流量工程,广域链路质量保障;华为广域网控制器协同,生态伙伴广域网控制器协同。

  6. WAN流量优化选路:SD-WAN集成协同,包括自动化部署、管理,流量调度,应用性能保障,链路成本优化;华为数通产品的SD-WAN协同,生态伙伴的SD-WAN协同。

ENS面向应用的多云多池应用连接

应用连接旨在实现跨云跨池的应用网络互联、应用治理、应用安全服务化,通过模型抽象屏蔽资源层网络的复杂性,并且兼容多种容器CNI网络方案,为客户提供:

  1. 跨域容器网络连接:集中管控跨K8S集群容器到容器的连接、容器到服务的访问,服务到容器的连接。K8S集群可以部署在不同的资源池上,也可以采用不同的CNI网络方案。

  2. 跨域容器服务互访:集中管控跨K8S集群服务自动发现、负载均衡、流量治理。

  3. 跨域容器网络安全:集中管控跨K8S集群的应用网络安全,支持基于命名空间粒度、网段粒度、容器粒度的一致安全策略管理。

总结

今天要向大家介绍的全新的 ENS 服务,专为政企客户的混合多态环境设计,致力于消除网络孤岛和应用孤岛,为客户提供“一张网”的视角,带来便捷、高效、安全、一致、高性能、稳定且简洁的网络体验。

点击关注,第一时间了解华为云新鲜技术~


Ubuntu是一款基于Debian GNU/Linux,支持x86、amd64(x64)和ppc架构,以桌面应用为主的Linux操作系统。其名称来自非洲南部的语言“ubuntu"(乌班图),Ubuntu是一种非洲民族的传统理念,同时也是南非共和国的建国准则之一,ubuntu的理念是“人道待人”,着重于人们之间相互的忠诚与交流。南非总统曼德拉解释:Ubuntu是一个概念,包含尊重、互助、分享、交流、关怀、信任、无私等多种内涵。

因此“Ubuntu系统”也恰如其名,开源、分享、免费、拥有广大的社区支持与交流,并受到众多国内外企业和个人用户的喜爱。但是Ubuntu操作系统有很多的版本,让人眼花缭乱,到底应该安装什么版本?怎么样选择才适合自己的电脑运行呢?本文将用德承工控机GM-1100来深度剖析其中的门道。

Ubuntu版本
Ubuntu的第一个正式版本于2004年10月正式推出,至今已经有20个年头了,Ubuntu在每年的4月和10月都会推出一个新系统版本,其编号以“西元年份的最后两位 . 发布月份”这样的格式来命名。

因此Ubuntu的第一个版本就称为4.10(2004年.10月),而且每个版本发布之后都还会持续的更新其底下的子版本,所以Ubuntu的版本有非常非常多种(可参考下表,仅列出大的版本号,子版本号太多就不一一列举,如果列出来就会像清明上河图一样长了)。

除了版本编号之外,每个Ubuntu版本在开发之初还有一个开发代号,这个代号也相当有趣,其命名方式为“形容词+动物名称”,且形容词和动物名称的第一个英文字母需相同,从Ubuntu 6.06开始这个首字母则按照英文字母表的排列顺序ABCD依次排序。

如2023年10月发布的Ubuntu 23.10,代号为 Mantic Minotaur(预言牛头怪),首字母为M,而下一代的代号按字母表的排列顺序为N,因此2024 年4月发布的Ubuntu 24.04 LTS,代号为 Noble Numbat(尊贵的袋食蚁兽),对应首字母为N。并且Ubuntu会为每个代号设计其专属的主题图像,Noble Numbat尊贵的袋食蚁兽,其主题图像中有2只自信满满的袋食蚁兽,坐立于皇冠的左右两侧,尽显其尊贵(如下图)。

另外,关于Ubuntu的版本,Ubuntu系统每2年还会出一个LTS版本(Long-Term Support长期支持),LTS版本都会有长达5年的支持维护时间,并在该版本编号后缀加上LTS,而没有带LTS的系统版本则多半为开发测试版本,支持的时间也比较短。

所以安装Ubuntu系统时建议尽量采用带有LTS的版本,如Ubuntu 24.04 LTS就是长期支持的稳定版本,该版本搭载最新的Linux 6.8内核,包含 Python 3.12、Ruby 3.2、PHP 8.3、Go 1.22、OpenJDK 21和.NET 8。

Ubuntu 24.04 LTS:
https://cn.ubuntu.com/download/desktop

Ubuntu内核
Ubuntu操作系统既然有这么多版本,那么应该安装什么版本才合适呢?这就需要提到所谓的“内核”(Kernel),内核是操作系统的核心部分,负责硬件、文件系统控制及多任务等功能。内核的版本号由“A.B.C” 三个部分的数字来组成,A代表主版本号,B代表次版本号,C代表较小的微调版本号,如内核4.4.117表示主版本号为4,次版本号为4,微调版本号为117,数字越大代表版本就越新。

Ubuntu的版本编号通常与内核版本号相关联,如Ubuntu 18.04是基于Linux内核4.15来开发的系统版本,所以每个新系统版本为了对市面上的新硬件有更好的兼容性,就会搭配更新的内核版本,Ubuntu 24.04 LTS就是搭载最新的Linux 6.8内核,由于Ubuntu版本较多,所以在此只列举出LTS版本的内核对照表。

lntel Linux系统支持版本
我们在前面了解Ubuntu的系统版本和内核版本之后,接着就可以按照电脑的CPU来选择适合的版本,以x86架构为例,我们可以在Intel Linux系统支持表中,查找CPU对应的平台所支持的Linux内核版本和系统版本。

德承工控机GM-1100可支持Intel 14/13/12代的处理器,支持这么多种CPU又该怎么选择呢?以第14代 Intel处理器为例,其平台(Platform)为 Raptor Lake-S Refresh,可以在系统支持表中查找到对应支持的Linux内核版本(Kernel Version)为6.1,Ubuntu系统版本则为22.04。

因此,在安装Ubuntu操作系统之前,我们需要先确认电脑的CPU及其对应的平台名称,再从平台名称找出对应的Linux内核版本,及对应的Ubuntu系统版本。看起来有点复杂,尤其是还需要知道CPU是什么平台才有办法查找。

所以本文特别整理出对应表便于查找,直接按照第几代的CPU就可找到对应的平台,进而找到对应的Linux内核版本,及适合的Ubuntu系统版本。如第8代 Intel CPU,其平台为Coffee Lake,支持的Linux内核版本为4.14,Ubuntu系统版本则为18.04。

Ubuntu操作系统在安装时不能选择更旧的系统版本,因为可能会存在兼容性的问题。由于新系统版本是为了对市面上的新硬件有更好的兼容性而发布的,所以我们除了查找到的适合版本之外,也可以选择安装更新的系统版本。

另外,18.04 LTS的常规支持已于2023年5月31日结束,所以我们可选择下一个版本的20.04 LTS来安装,或者是选择Ubuntu操作系统最新的24.04 LTS。

Ubuntu查看版本
我们在安装好Ubuntu系统后,可在Ubuntu系统中查看系统版本和内核版本
以Ubuntu20.04.4 LTS为例,按Ctrl + Alt + T 打开终端,在终端中输入命令:

查看Ubuntu版本号
cat /etc/issue
显示:Ubuntu 20.04.4 LTS \n \l

查看内核版本号
uname –r
显示:5.13.0-30-generic

查看内核详细资讯
uname –a
显示:Linux ubuntu 5.13.0-30-generic #40~20.04.4-Ubuntu SMP Fri Dec 27 13:10:12 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux

结语
如何在众多Ubuntu版本中挑选出最适配自身需求的系统版本?综上所述我们知道Ubuntu的版本固然很多,而且每个版本还有其底下的多个子版本,但是我们在安装时应该优先选择带有LTS的长期支持版本。

接着,我们需要确认电脑的CPU及其对应的平台名称,再从平台名称找出对应的Linux内核版本,及对应的Ubuntu系统版本。德承工控机GM-1100支持Intel 12代到14代的多种CPU,以这台工控机为例可以清楚的知道第13/14代CPU支持Linux内核版本为6.1,Ubuntu版本为22.04,而第12代CPU支持Linux内核版本为5.10/5.15,Ubuntu版本为22.04。

本文中所提供的对应表,可轻松按照Intel第几代的CPU来查找,直接对应支持的Linux内核版本及Ubuntu系统版本,如果对Ubuntu系统有兴趣,或是需要安装此系统的爱好者,建议可收藏此文章,便于后续查找适配的系统版本。

参考网址1:
https://cn.ubuntu.com/

参考网址2:
https://www.cincoze-china.com/goods_info.php?id=537

参考网址3:
https://www.intel.cn/content/www/cn/zh/partner/showcase/offering/a5bHo0000003vtqIAA/gm1100-embedded-mxm-gpu-computer.html

1 提取视频流/音频流

// 分离视频流和音频流
ffmpeg -i input_file -vcodec copy -an output_file_video
ffmpeg -i input_file -acodec copy -vn output_file_audio

2 视频转封装

ffmpeg –i test.mp4 –vcodec copy –acodec copy –f m4v test.m4v
ffmpeg –i test.avi –vcodec copy –acodec copy –f m4v test.m4v

3 视频转码

ffmpeg –i test.mp4 –vcodec h264 –s 352*278 –an –f m4v test.264
ffmpeg –i test.mp4 –vcodec h264 –bf 0 –g 25 –s 352*278 –an –f m4v test.264
ffmpeg –i test.avi -vcodec mpeg4 –vtag xvid –qsame test_xvid.avi

部分选项说明:-bf,B 帧数量;-g,gop 大小控制;-s,分辨率。

4 视频封装

ffmpeg –i video_file –i audio_file –vcodec copy –acodec copy output_file

5 视频剪切

ffmpeg -ss 0:1:30 -t 0:0:20 -i input.avi -vcodec copy -acodec copy output.avi

部分选项说明:-r, 提取图像的频率;-ss,开始时间;-t 持续时间。

6 视频截图

先运行如下命令测试一下:

ffmpeg -ss 00:00:08 -i test.mp4 -f image2 test.jpg

发现截图已经正常生成,但是命令行有如下报错信息:
[image2 @ 0x1370f80] Could not get frame filename number 2 from pattern 'test.jpg' (either set update or use a pattern like %03d within the filename pattern)
av_interleaved_write_frame(): Invalid argument

参考 “
Solutions to some ffmpeg errors and messages
” 得到原因如下:

这个错误通常是因为输出名不正常或者少了某些选项:
如果输出单幅图像,应添加 “-frames:v 1” 输出选项;
如果输出一系列图像,应当使用正确的名称形式,例如输出文件名为 output_%03d.png 时,将会依次生成 output_001.png, output_002.png, output_003.png 等;
如果输出单幅图像,总是用最新的图像覆盖掉旧图像,应添加 “-update 1” 选项。

根据以上建议,修改命令如下:

  1. 提取单幅图像
    第8秒处的提取一帧图像:
ffmpeg -ss 00:00:08 -i ring.mp4 -frames:v 1 -f image2 ring.jpg

各参数说明如下:
“-ss 00:00:08”:输入选项,截取输入文件中第8秒处的图像
“-frames:v 1”:输出选项,往输出中写入一个视频帧
“-f image2”:输出选项,指定输出格式为image2

注意“-ss 00:00:08”应放在“-i ring.mp4”之前,作为输入选项,可以很快就能获得视频截图。如果放在 “-i ring.mp4” 之后就成了输出选项,作输出选项时,ffmpeg 会一直从输入文件中读取,直到到达指定时间点,才能获取截图,如果凑巧截图的位置在文件尾,则要等整个视频播放完才能得到视频截图。

  1. 提取一系列图像
    每隔 1 秒(1Hz)提取一帧图像:
ffmpeg -i ring.mp4 -r 1 -f image2 ring-%3d.jpg

“-r 1”:输出选项,设置帧率,通过重复(比输入文件帧率大)或丢弃(比输入文件帧率小)视频帧来满足此帧率

从第 8 秒开始的持续 10 秒的视频里,每隔 1 秒(1Hz)提取一帧图像:

ffmpeg -ss 00:00:08 -t 00:00:10 -i ring.mp4 -r 1 -f image2 ring-%03d.jpg

从第 8 秒开始的持续 10 秒的视频里,提取前 3 帧图像:

ffmpeg -ss 00:00:08 -t 00:00:10 -i ring.mp4 -frames:v 3 -f image2 ring-%03d.jpg
  1. 提取一帧中的一场图像
    ffmpeg -i video.avi -frames:v 1 -vf field=top top%d.png

7 视频录制

录制网络流

ffmpeg –i rtsp://192.168.2.104:1235/test –vcodec copy out.avi

录制测试图(testsrc)视频,时长 12 秒

ffmpeg -ss 00:00:00 -t 00:00:12 -f lavfi -i testsrc testsrc.flv

8 保存YUV文件

ffmpeg -i tiger.m2ts -an -c:v rawvideo -pixel_format yuv422p -ss 00:00:08 -frames:v 5 tiger_422_8b.yuv
ffmpeg -i tiger.m2ts -an -c:v rawvideo -pixel_format yuv422p10 -ss 00:00:08 -frames:v 5 tiger_422_10b.yuv
ffmpeg -i fifa.ts -an -c:v rawvideo -vf format=yuv422p -ss 00:01:00 -frames:v 5 fifa_3840x2160_422_8b.yuv
ffmpeg -f lavfi -i nullsrc=s=3840x2160:r=60,lutrgb=0:255:0 -frames:v 5 -vf format=yuv422p -c:v rawvideo green_3840x2160_422p_8b.yuv