FFmpeg 视频处理

简介

FFmpeg是一个开源的跨平台多媒体处理工具套件,它包含了一系列用于处理音频、视频、字幕和图像的库和程序。FFmpeg可以执行多种多媒体处理操作,如格式转换、编码、解码、流媒体传输等,它被广泛应用于视频编辑、转码、流媒体服务器以及其他多媒体处理领域。

FFmpeg的历史可以追溯到2000年,最初由法国程序员Fabrice Bellard创建。Fabrice Bellard最初创建了一个叫做FFmpeg的项目,以实现MPEG视频的解码。FFmpeg最初只是一个命令行工具,但随着时间的推移,它不断发展壮大,并且逐渐成为一个完整的多媒体处理工具套件。

应用场景和具体实现功能

格式转换:FFmpeg可以将一个多媒体文件转换为不同的格式,如将视频文件转换为不同的编码格式(如H.264、HEVC、VP9)或容器格式(如MP4、MKV、AVI)。

视频编码和解码:FFmpeg可以对视频进行编码和解码,以改变视频的编码格式或进行视频文件的压缩。

音频编码和解码:FFmpeg可以对音频进行编码和解码,以改变音频的编码格式或进行音频文件的压缩。

视频剪辑和裁剪:FFmpeg可以从视频文件中提取特定的片段,或对视频进行裁剪,以获得所需的时间段或尺寸。

视频合并和拼接:FFmpeg可以将多个视频文件合并成一个,或将多个视频片段拼接在一起,创建一个连续的视频。

视频转码和优化:FFmpeg可以对视频进行转码,改变其编码参数、分辨率、比特率等,以获得更好的视觉效果或适应特定的设备或平台需求。

视频处理和滤镜:FFmpeg提供了多种滤镜和效果,可以对视频进行处理,如添加水印、调整亮度、对比度、色彩等。

实时流媒体传输:FFmpeg可以将多媒体内容实时编码并流式传输到网络上,以实现实时视频直播、视频会议等应用。

屏幕录制:FFmpeg可以捕捉屏幕上的活动,并将其保存为视频文件,用于创建教学视频、演示文稿等。

生成缩略图:FFmpeg可以从视频或音频文件中提取关键帧图像

视频分析和处理:FFmpeg提供了一些工具和库,可以进行视频质量评估、视频编码参数分析、视频处理算法实现等。

Demo

肉眼无损压缩

参考 -crf 参数优化

FFmpeg视频转码技巧之-crf参数(H.264篇)

x265的编码参数preset级别对性能的影响

ffmpeg -i 坐船.mp4 -c:v libx264 -preset medium -crf 28 -c:a copy demo.mp4
原始大小
压缩后

给视频添加背景音乐

参考

截取音乐片段

ffmpeg -i 植地雅哉\ -\ 静寂.flac  -ss 00:00:19 -t 9 a2.mp3 -y

-i 输入文件
-ss 开始时间
-t 持续时间
-y 覆盖

去除视频原声音

ffmpeg -i 16072614418853318.mp4  -an v2.mp4 -y

合并视频和音频,时长要一致

ffmpeg -i a2.mp3 -i v2.mp4 demo2.mp4

合并视频和音乐,保留视频原声音

ffmpeg -i a3.mp3 -i 16072664036058512.mp4 -threads 2 -filter_complex amix=inputs=2:duration=first:dropout_transition=0 optout.mp4 -y

视频加水印

ffmpeg -i 视频输入路径 -vf "movie=水印图片路径 [watermark]; [in][watermark] overlay=x坐标:y坐标 [out]" -y 视频输出路径

获取转码进度

使用GPU加速

参考

ubuntu 查看显卡驱动

CUDA 工具包

sudo apt install nvidia-cuda-toolkit

本地安装

wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/cuda-ubuntu2004.pin
sudo mv cuda-ubuntu2004.pin /etc/apt/preferences.d/cuda-repository-pin-600
wget https://developer.download.nvidia.com/compute/cuda/11.1.0/local_installers/cuda-repo-ubuntu2004-11-1-local_11.1.0-455.23.05-1_amd64.deb
sudo dpkg -i cuda-repo-ubuntu2004-11-1-local_11.1.0-455.23.05-1_amd64.deb
sudo apt-key add /var/cuda-repo-ubuntu2004-11-1-local/7fa2af80.pub
sudo apt-get update
sudo apt-get -y install cuda

报错提示

The following packages have unmet dependencies:
 cuda : Depends: cuda-11-1 (>= 11.1.0) but it is not going to be installed
E: Unable to correct problems, you have held broken packages.

解决

sudo apt install cuda-11-1

网络安装

wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/cuda-ubuntu2004.pin
sudo mv cuda-ubuntu2004.pin /etc/apt/preferences.d/cuda-repository-pin-600
sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/7fa2af80.pub
sudo add-apt-repository "deb https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/ /"
sudo apt-get update
sudo apt-get -y install cuda

验证是否安装成功

验证安装

~$ /usr/local/cuda-11.1/bin/nvcc -V
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2020 NVIDIA Corporation
Built on Tue_Sep_15_19:10:02_PDT_2020
Cuda compilation tools, release 11.1, V11.1.74
Build cuda_11.1.TC455_06.29069683_0

重新编译ffmpeg 安装nv-codec-headers库

ffmpeg -hwaccels命令查看支持的硬件加速选项

~$ ffmpeg -hwaccels

Hardware acceleration methods:
vdpau
cuda
vaapi
drm
opencl
cuvid

cuvid的硬件加速选项,这就是CUDA提供的GPU视频编解码加速选项

查看cuvid提供的GPU编解码器ffmpeg -codecs | grep cuvid

DEV.LS h264                 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (decoders: h264 h264_v4l2m2m h264_cuvid ) (encoders: libx264 libx264rgb h264_nvenc h264_omx h264_v4l2m2m h264_vaapi nvenc nvenc_h264 )
 DEV.L. hevc                 H.265 / HEVC (High Efficiency Video Coding) (decoders: hevc hevc_v4l2m2m hevc_cuvid ) (encoders: libx265 nvenc_hevc hevc_nvenc hevc_v4l2m2m hevc_vaapi )
 DEVIL. mjpeg                Motion JPEG (decoders: mjpeg mjpeg_cuvid ) (encoders: mjpeg mjpeg_vaapi )
 DEV.L. mpeg1video           MPEG-1 video (decoders: mpeg1video mpeg1_v4l2m2m mpeg1_cuvid )
 DEV.L. mpeg2video           MPEG-2 video (decoders: mpeg2video mpegvideo mpeg2_v4l2m2m mpeg2_cuvid ) (encoders: mpeg2video mpeg2_vaapi )
 DEV.L. mpeg4                MPEG-4 part 2 (decoders: mpeg4 mpeg4_v4l2m2m mpeg4_cuvid ) (encoders: mpeg4 libxvid mpeg4_v4l2m2m )
 D.V.L. vc1                  SMPTE VC-1 (decoders: vc1 vc1_v4l2m2m vc1_cuvid )
 DEV.L. vp8                  On2 VP8 (decoders: vp8 vp8_v4l2m2m libvpx vp8_cuvid ) (encoders: libvpx vp8_v4l2m2m vp8_vaapi )
 DEV.L. vp9                  Google VP9 (decoders: vp9 vp9_v4l2m2m libvpx-vp9 vp9_cuvid ) (encoders: libvpx-vp9 vp9_vaapi )
nvidia-smi 查看GPU使用情况

watch -n 1 nvidia-smi 定时间隔一秒查看信息

测试

ffmpeg -hwaccel cuvid -c:v h264_cuvid -i 坐船.mp4 -c:v h264_nvenc -preset medium -crf 28 -c:a copy -y gpu.mp4

如果是手机拍摄的视频会报上述错误,说明视频有旋转信息,手机拍摄的视频自带90°旋转。需要加 -noautorotate 参数

ffmpeg -hwaccel cuvid -c:v h264_cuvid -noautorotate -i 坐船.mp4 -c:v h264_nvenc -preset medium -crf 28 -c:a copy -y gpu.mp4
  • -hwaccel cuvid 指定使用cuvid硬件加速
  • -c:v h264_cuvid:使用h264_cuvid进行视频解码
  • -c:v h264_nvenc:使用h264_nvenc进行视频编码
  • -noautorotate 去除视频旋转信息

去除视频旋转信息后视频,文件大小变得很小,但是画质很糊

ffmpeg -hwaccel cuvid -c:v h264_cuvid -noautorotate -i 2019.mp4 -c:v h264_nvenc -preset medium -crf 28 -c:a copy -y 2019gpu.mp4

使用GPU压缩视频最后文件大小没变,crf参数相同。

以目前掌握的知识来说,推荐使用CPU压缩,缺点是比GPU慢。后续深入了解后再补充

截取封面图

要使用FFmpeg截取视频的封面,可以使用以下命令:

ffmpeg -i input.mp4 -vframes 1 -q:v 2 output.jpg

这个命令的含义是:

-i input.mp4 指定输入文件为 input.mp4,你可以将其替换为你实际的视频文件名。
-vframes 1 指定要提取的帧数量,这里设置为1,即只提取一帧,也就是封面。
-q:v 2 指定输出图像的质量,范围是0-31,其中0表示最高质量。这里设置为2,表示输出较高质量的图像。
output.jpg 指定输出文件名,这里设置为 output.jpg,你可以根据需要修改。
执行命令后,FFmpeg将从输入视频中提取一帧,并将其保存为JPEG图像文件(封面),命名为 output.jpg

视频导出图片

首先使用ffmpeg -i xxx.mp4 查看 视频fps 信息 56.20 fps

然后执行

ffmpeg -i IMG_1529.MP4 -f image2 -vf fps=56.20 -qscale:v 2 IMG_1529/img%04d.jpg

参数说明

-i: 视频路径 -f: 图片格式 fps=5: 每5s取一帧 fps=1/5: 每1s取5帧 img%04d.jpg: 生成的图片命名格式 IMG_1529为输出目录

图片序列合并成视频

ffmpeg -f image2 -i image%d.jpg video.mpg

截取视频片段

使用 -ss 和 -t 选项,从第0秒开始,向后截取31秒视频,并保存

ffmpeg -ss 00:00:00 -i video.mp4 -vcodec copy -acodec copy -t 00:00:31 output1.mp4

从第01:33:30 开始,向后截取 00:47:16 视频,并保存

ffmpeg -ss 01:33:30 -i video.mp4 -vcodec copy -acodec copy -t 00:47:16 output2.mp4

合并视频

  把剪切得到的两个视频合并成一个视频

  使用 TS格式拼接视频

  先将 mp4 转化为同样编码形式的 ts 流,因为 ts流是可以 concate 的,先把 mp4 封装成 ts ,然后 concate ts 流, 最后再把 ts 流转化为 mp4。

ffmpeg -i output1.mp4 -vcodec copy -acodec copy -vbsf h264_mp4toannexb output1.ts
ffmpeg -i output2.mp4 -vcodec copy -acodec copy -vbsf h264_mp4toannexb output2.ts

 为了减少命令的输入,需要一个filelist.txt文件,里面内容如下

file 'output1.ts'
file 'output2.ts'

合并视频命令

ffmpeg -f concat -i filelist.txt -acodec copy -vcodec copy -absf aac_adtstoasc output.mp4

视频快速转MP3

ffmpeg -i 让一切情绪流动.MP4 -f mp3 让一切情绪流动.mp3

FFMpeg无损合并视频的多种方法

FFmpeg批量提取视频的某一帧作为封面

ffmpeg中文文档

无限极分类的多种实现方式

递归

从数据库中查询出所有数据,然后递归处理

$category = [[
    'id' => 1,
    'pid' => 0,
    'name' => '1级分类',
], [
    'id' => 2,
    'pid' => 1,
    'name' => '2级分类',
], [
    'id' => 3,
    'pid' => 2,
    'name' => '3级分类',
], [
    'id' => 4,
    'pid' => 3,
    'name' => '4级分类',
], [
    'id' => 5,
    'pid' => 4,
    'name' => '5级分类'
], [
    'id' => 6,
    'pid' => 6,
    'name' => '6级分类'
]];

//递归成树形
function recurSionToTree(array $array = [], $pid = 0)
{
    $result = [];

    foreach ($array as $key => $value) {

        if ($value['pid'] == $pid) {
            $children = recurSionToTree($array, $value['id']);

            if ($children) {
                $value['children'] = $children;
            }

            $result[] = $value;
        }
    }

    return $result;
}

引用

从数据库查询出所有数据,然后遍历

function refToTree($data)
{
    $items = array();

    foreach ($data as $v) {
        $items[$v['id']] = $v;
    }

    $tree = array();

    foreach ($items as $k => $item) {
        if (isset($items[$item['pid']])) {
            $items[$item['pid']]['children'][] = &$items[$k];
        } else {
            $tree[] = &$items[$k];
        }
    }

    return $tree;
}

冗余字段,空间换时间

参考连接:https://learnku.com/courses/ecommerce-advance/7.x/database-structure/9086

在开始之前,我们需要先整理好 categories 表的字段名称和类型:

字段名称描述类型加索引缘由
id自增长 IDunsigned big int主键
name类目名称varchar
parent_id父类目 IDunsigned big int, null外键
is_directory是否拥有子类目tinyint
level当前类目层级unsigned int
path该类目所有父类目 idvarchar

这里我们需要解释一下 path 字段的意义,在无限级分类的实现中我们经常会遇到以下几个场景:

  • 场景一:查询一个类目的所有祖先类目,需要递归地去逐级查询父类目,会产生较多的 SQL 查询,从而影响性能。
  • 场景二:查询一个类目的所有后代类目,同样需要递归地逐级查询子类目,同样会产生很多 SQL 查询。
  • 场景三:判断两个类目是否有祖孙关系,需要从层级低的类目逐级往上查,性能低下。

而 path 字段就是用于解决这些问题而存在的,path 字段会保存该类目所有祖先类目的 ID,并用字符 - 将这些 ID 分隔开,根类目的 path 字段为 -。比如如下类目:

[
    [
        "id" => 1,
        "name" => "手机配件",
        "parent_id" => null,
        "level" => 0,
        "path" => "-"
    ],
    [
        "id" => 2,
        "name" => "耳机",
        "parent_id" => 1,
        "level" => 1,
        "path" => "-1-"
    ],
    [
        "id" => 3,
        "name" => "蓝牙耳机",
        "parent_id" => 2,
        "level" => 2,
        "path" => "-1-2-"
    ],
    [
        "id" => 4,
        "name" => "移动电源",
        "parent_id" => 1,
        "level" => 1,
        "path" => "-1-"
    ],
];

对应的类目树如下:

手机配件(1)
 ├─ 耳机(2)
 │   └─ 蓝牙耳机(3)
 └─ 移动电源(4)

现在我们再来逐一分析刚刚的几个场景:

场景一,查询『蓝牙耳机』的所有祖先类目:取出 path 字段的值 -1-2-,以 - 为分隔符分割字符串并过滤掉空值,得到数组 [1, 2] ,然后使用 Category::whereIn('id', [1, 2])->orderBy('level')->get() 即可获得排好序的所有父类目。

场景二,查询『手机配件』的所有后代类目:取出自己的 path 值 -,然后追加上自己的 ID 字段得到 -1-,然后使用 Category::where('path', 'like', '-1-%')->get() 即可获得所有后代类目。

场景三,判断『移动电源』与『蓝牙耳机』是否有祖孙关系:取出两者中 level 值较大的类目『蓝牙耳机』的 path 值 -1-2- 并赋值给变量 $highLevelPath,取另外一个类目的 path 值并追加该类目的 ID 得 -1-4- 并赋值给变量 $lowLevelPath,然后只需要判断变量 $highLevelPath 是否以 $lowLevelPath 开头,如果是则有祖孙关系。

可以看到我们通过新增一个冗余的 path 字段,就能很好地解决性能问题,这是一种很典型的(存储)空间换(执行)时间策略。

预排序树

参考连接

https://www.jianshu.com/p/48f6db8ea524

https://www.cnblogs.com/sonicit/archive/2013/05/21/3090518.html

记录Let’s encrypt 证书导致的两个严重问题

问题一

起因,公司的某项目APP客户反馈,ios打开数据响应很慢

2020年4月份出现,在ios系统上,证书解析非常慢,导致ios调取接口经常超时,而且时很多运营商都出现过这个问题,时快时慢.

起初以为时服务器网络问题,在PC上通过mtr检测后发现服务器和网络正常

使用ios网络诊断工具Best Net Tools 检测发现服务器和网络正常

最终通过人工对比测试发现,国内使用Let’s encrypt证书的网站,和其它证书赛克铁门,发现Let’s encrypt证书在ios系统上响应很慢

问题二

起因,公司某项目调取第三方同步数据接口的队列报错

GuzzleHttp\Exception\RequestException: cURL error 60: SSL certificate problem: unable to get local issuer certificate (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)

使用postman开启ssl验证接口没有响应,

参考https://stackoverflow.com/questions/46080133/laravel-curl-error-60-ssl-certificate-unable-to-get-local-issuer-certificate 修改php.ini curl.cainof 和openssl.cafile 配置新的证书后,还是报错,和原先配置的证书是一样的,所以并不是这个证书的原因.

最后解决方法,使用guzzle的配置项 verify 设置为false不验证ssl

文档 https://guzzle-cn.readthedocs.io/zh_CN/latest/request-options.html#verify

总结

解决问题后,需要问为什么会出现这些问题,重新复习一下ssl相关知识和原理,后续慢慢完善

是什么?简介

干什么?用途

怎么干?应用

为什么?工作原理

网络基础知识

网络协议 百科

是程序(人)与计算机,计算机与计算机交流(通讯)的基础,通俗的比喻,人与人之间交流需要同一种语言,计算机的网络通讯需要协议。

协议的三要素

语法:一断内容要符合一定的规则和格式,例如http协议的开头是http://xxx.com

语义:这一段内容规则代表的含义,例如http开头就表示http协议

顺序:先干啥后干啥

网络分层

7层是指OSI七层协议模型,主要是:应用层(Application)表示层(Presentation)会话层(Session)传输层(Transport)网络层(Network)数据链路层(Data Link)物理层(Physical)

5层只是OSI和TCP/IP的综合,是业界产生出来的非官方协议模型,但是很多具体的应用。实际应用还是TCP/IP的四层结构。为了方便可以把下两层称为网络接口层。五层体系结构包括:应用层运输层网络层数据链路层物理层。 

4层是指TCP/IP四层模型,主要包括:应用层运输层网际层网络接口层

网络为什么要分层

复杂的程序都要分层,这是程序设计的要求

个人理解,分层相当于人类社会的分工协作,目的是提升效率便于管理,很多网络程序都是采用这种模型,不同的进程做不同的事情。

复杂的事情简单化就要拆分。

域名

百度百科 维基百科

IP地址

IP(英语:Internet Protocol Address)是一种在Internet上的给主机编址的方式,也称为网际协议地址。常见的IP地址,分为IPv4IPv6两大类。

通俗的比喻,就相当于我们的通讯地址(你住哪),邮件快递都需要通讯地址。

MAC地址

MAC地址也叫物理地址、硬件地址,由网络设备制造商生产时烧录在网卡(Network lnterface Card)的EPROM(一种闪存芯片,通常可以通过程序擦写)

通俗的比喻,相当于我们的身份证,身份证号是唯一的不能不变。但是可以造假,操作系统识别出来的mac地址是可以更改的,它只不过是一个字符串。我们常说的修改mac指的是修改电脑中记录的既注册表中的记录

为什么需要两种地址

送快递的时候,既要验证地址对不对,又要验证人对不对,ip4地址不够用,很多网络对外是一个公网IP

公有地址 百科

公有地址(Public address)由Inter NIC(Internet Network Information Center因特网信息中心)负责。
这些IP地址分配给注册并向Inter NIC提出申请的组织机构。通过它直接访问因特网。即常说的公网IP查询

私有地址 百科

在现在的网络中,IP地址分为公网IP地址和私有IP地址。公网IP是在Internet使用的IP地址,而私有IP地址则是在局域网中使用的IP地址。私有IP地址是一段保留的IP地址。只使用在局域网中,无法在Internet上使用。即内网IP

地址范围

无类型域间选路(CIDR)百科

产生原因:地址划分不合理

C 类地址能包含的最大主机数量实在太少了,只有 254 个。当时设计的时候恐怕没想到,现在估计一个网吧都不够用吧。而 B 类地址能包含的最大主机数量又太多了。6 万多台机器放在一个网络下面,一般的企业基本达不到这个规模,闲着的地址就是浪费。

将 32 位(说的是二进制形式)的 IP 地址一分为二,前面是网络号,后面是主机号。从哪里分呢?你如果注意观察的话可以看到,10.100.122.2/24,这个 IP 地址中有一个斜杠,斜杠后面有个数字 24。这种地址表示形式,就是 CIDR。后面 24 的意思是,32 位中,前 24 位是网络号,后 8 位是主机号。

一般云主机的安全组白名单设置使用这种规则。 反爬虫笔记

特殊地址

广播地址 百科

广播地址(Broadcast Address)是专门用于同时向网络中(通常指同一子网)所有工作站进行发送的一个地址。

任何第一个字节大于223小于240的IP地址(范围224.0.0.1-239.255.255.254)是多点广播地址

网络通讯方式有单播,广播,组播。广播应用,有线电视,DHCP服务

通俗的比喻,老师需要对全班发送相同通知(信息),如果一个一个叫到办公室里说,非常好使,直接在教师里通知大家效率高。

子网掩码 百科

子网掩码(subnet mask)又叫网络掩码地址掩码、子网络遮罩,它是一种用来指明一个IP地址的哪些位标识的是主机所在的子网,以及哪些位标识的是主机的位掩码。子网掩码不能单独存在,它必须结合IP地址一起使用。子网掩码只有一个作用,就是将某个IP地址划分成网络地址主机地址两部分。

作用

子网掩码是在IPv4地址资源紧缺的背景下为了解决lP地址分配而产生的虚拟lP技术,通过子网掩码将A、B、C三类地址划分为若干子网,从而显著提高了IP地址的分配效率,有效解决了IP地址资源紧张的局面。另一方面,在企业内网中为了更好地管理网络,网管人员也利用子网掩码的作用,人为地将一个较大的企业内部网络划分为更多个小规模的子网,再利用三层交换机的路由功能实现子网互联,从而有效解决了网络广播风暴和网络病毒等诸多网络管理方面的问题

0.0.0.0 百科

代表当前主机

127.0.0.1 百科

127.0.0.1是回送地址,指本地机,一般用来测试使用。回送地址(127.x.x.x)是本机回送地址(Loopback Address),即主机IP堆栈内部的IP地址,主要用于网络软件测试以及本地机进程间通信,无论什么程序,一旦使用回送地址发送数据,协议软件立即返回,不进行任何网络传输。

网关 百科

网关(Gateway)又称网间连接器、协议转换器。网关在网络层以上实现网络互连,是复杂的网络互连设备,仅用于两个高层协议不同的网络互连。网关既可以用于广域网互连,也可以用于局域网互连。 网关是一种充当转换重任的计算机系统或设备。使用在不同的通信协议、数据格式或语言,甚至体系结构完全不同的两种系统之间,网关是一个翻译器。与网桥只是简单地传达信息不同,网关对收到的信息要重新打包,以适应目的系统的需求。同层–应用层

通俗比喻,大家都知道,从一个房间走到另一个房间,必然要经过一扇门。同样,从一个网络向另一个网络发送信网关息,也必须经过一道“关口”,这道关口就是网关。顾名思义,网关(Gateway [1] 就是一个网络连接到另一个网络的“关口”。也就是网络关卡

TIPS 由于历史的原因,许多有关TCP/IP的文献曾经把网络层使用的路由器称为网关,在今天很多局域网采用都是路由来接入网络,因此通常指的网关就是路由器的IP

网关实质上是一个网络通向其他网络的IP地址。

DNS 百科

域名系统(服务)协议(DNS)一种分布式网络目录服务,主要用于域名与 IP 地址的相互转换

通俗的解释,即使访问网站如果让用户输入ip地址,太麻烦,不好记(缺少语义),于是发明了URL来定位站。

DNS是就是URL和IP的映射关系,通过URL查询到对应服务器的IP,然后访问。

查找IP地址的过程,这个过程就是域名解析

域名注册后,注册商为域名提供免费的静态解析服务。
一般的域名注册商不提供动态解析服务,如果需要用动态解析服务,需要向动态域名服务商支付域名动态解析服务费。

本机的DNS是hosts文件,操作系统网络程序会优先查询hosts

Hosts文件 百科

Hosts是一个没有扩展名的系统文件,可以用记事本等工具打开,其作用就是将一些常用的网址域名与其对应的IP地址建立一个关联“数据库”,当用户在浏览器中输入一个需要登录的网址时,系统会首先自动从Hosts文件中寻找对应的IP地址,一旦找到,系统会立即打开对应网页,如果没有找到,则系统会再将网址提交DNS域名解析服务器进行IP地址的解析

路由 百科

路由(routing)是指分组从源到目的地时,决定端到端路径的网络范围的进程 [1] 。路由工作在OSI参考模型第三层——网络层数据包转发设备。路由器通过转发数据包来实现网络互连。虽然路由器可以支持多种协议(如TCP/IP、IPX/SPX、AppleTalk等协议),但是在我国绝大多数路由器运行TCP/IP协议路由器通常连接两个或多个由IP子网或点到点协议标识的逻辑端口,至少拥有1个物理端口。路由器根据收到数据包中的网络层地址以及路由器内部维护的路由表决定输出端口以及下一跳地址,并且重写链路层数据包头实现转发数据包。路由器通过动态维护路由表来反映当前的网络拓扑,并通过网络上其他路由器交换路由和链路信息来维护路由表。

静态路由 百科

静态路由(英语:Static routing),一种路由的方式,路由项(routing entry)由手动配置,而非动态决定。与动态路由不同,静态路由是固定的,不会改变,即使网络状况已经改变或是重新被组态。一般来说,静态路由是由网络管理员逐项加入路由表

动态路由 百科

动态路由是指路由器能够自动地建立自己的路由表,并且能够根据实际情况的变化适时地进行调整

网络协议

UDP协议

UDP协议介绍,无状态,无响应,不保证可靠性会丢包

场景:

1.需要资源少,在网络情况比较好的内网,或者对于丢包不敏感的应用

2.不需要一对一沟通,建立连接,而是可以广播的应用

3.需要处理速度快,时延低,可以容忍少数丢包,但是要求即便网络拥塞,也毫不退缩,一往无前的时候

TCP协议

TCP消息类型

信息描述
Syn用于启动和建立连接。它还可以帮助您在设备之间同步序列号。
ACK帮助对方确认它已收到SYN。
SYN-ACK来自本地设备的SYN消息和先前数据包的ACK。
FIN (鳍)用于终止连接。

三次握手

三次握手时序图

开始,客户端和服务端都处于 CLOSED 状态。

先是服务端主动监听某个端口,处于 LISTEN 状态。然后客户端主动发起连接 SYN,之后处于 SYN-SENT 状态 (第一次)

服务端收到发起的连接,返回 SYN,并且 ACK 客户端的 SYN,之后处于 SYN-RCVD 状态(第二次)

客户端收到服务端发送的 SYN 和 ACK 之后,发送 ACK 的 ACK,之后处于 ESTABLISHED 状态,因为它一发一收成功了(第三次)

服务端收到 ACK 的 ACK 之后,处于 ESTABLISHED 状态,因为它也一发一收了

四次挥手

四次挥手时序图

第一次挥手, A发送FIN,进入FIN_WAIT1状态,B收到FIN 进入CLOSED_WAIT状态,

第二次挥手,A收到ACK,进入FIN_WAIT_2状态(如果此时B断开,则A将永远留在这个状态,TCP协议没有对这个状态的处理,linux有,可以通过tcp_fin_timeout草书,设置超时

第三次挥手,B发送FIN,ACK到达A,

第四次挥手,A发送ACK给B,进入TIME_WAIT时间(这个时间足够长,足够B重新发送第三方次挥手,然后A重新进行第四次挥手,可以防止产生混乱,如端口被新应用占领,等到原先的包都失效,在空出新端口)

协议规定等待时间为 2MSL(2分钟),MSL 是 Maximum (最大) Segment (段) Lifetime (一生) ,报文最大生存时间。任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。实际应用中常用的是30秒,1分钟和2分钟。

TCP状态机

DNS 协议

这个协议就像是个地址簿,主要负责 “域名” => “IP 地址” 的查询。每次我们要邮寄信件之前都要拿出来查一查。

DHCP 协议

DHCP 全称叫动态主机配置协议(Dynamic Host (主机) Configuration Protocol (协议) ),主要负责计算机接入网络时的初始化。计算机刚开始就只有网卡的 MAC 地址,通过 DHCP 可以给它分配 IP 地址,并得到默认网关地址(这很重要,不知道网关就上不了网)和 DNS 服务器的地址。有了这些东西,这台计算机就可以和外界通讯了

ARP 协议

IP => Mac 根据ip地址获取mac地址

ARP 全称叫地址解析协议( Address (地址) Resolution Protocol),它服务于现在局域网中最流行的以太网协议。在以太网中,ARP 协议负责解析远程主机 IP 地址对应的 MAC 地址。之所以需要 ARP 协议,是因为我们平常应用程序连接目标计算机进行网络通讯时,都是提供了域名或 IP 地址。但对以太网来说,要想发信件出去,它要的是对方的 MAC 地址

RARP 协议

RARP 全称叫反向地址转换协议(Reverse Address (地址) Resolution Protocol (协议) )。顾名思义,它和 ARP 协议相反,负责的是 MAC 地址到 IP 地址的转换。RARP 协议已经被上面的 DHCP 协议所取代,平常用不太到了。

ICMP 协议

ICMP 全称叫互联网控制报文协议(Internet Control Message Protocol),它能够检测网路的连线状况,以保证连线的有效性。基于这个协议实现的常见程序有两个:ping 和 traceroute,它们可以用来判断和定位网络问题。

IGMP 协议

IGMP 全称叫互联网组管理协议(Internet Group Management Protocol (协议) ),它负责 IP 组播(Multicast)成员管理


数据传输过程

笔记参考

极客时间 趣谈网络协议

网络配置要素 https://www.cnblogs.com/guojun-junguo/p/9966412.html

网络分层 https://blog.csdn.net/cc1949/article/details/79063439

网络通讯模式 https://www.cnblogs.com/hnrainll/archive/2011/09/01/2161839.html

极客时间 许式伟架构课 IP网络:连接世界的桥梁

TCP协议(上):因性恶而复杂,先恶后善反轻松

TCP协议(下):西行必定多妖孽,恒心智慧消磨难

TCP 三次握手(SYN,SYN-ACK,ACK)

微信图片压缩算法

微信是一个很好的参照物,被大家广为使用并接受。这个扩展就是通过发送微信朋友圈和聊天会话发送了大量图片,对比原图与微信压缩后的图片逆向推算出来的压缩算法。

TIPS:

  • 符号表示无穷大
  • [ 1,3 ) 这是一个区间,表示从1到3之间的所有实数,左边中括号表示闭区间,也就是把1算在区间内。右边小括号表示不包括3。

算法 Luban

参考:https://zhuanlan.zhihu.com/p/56595874

1.判断图片比例值,是否处于以下区间

  • [1,0.5625)即图片处于[1:1 ~ 9:16] 比例范围内
  • [0.5625,0.5)即图片处于[9:16 ~ 1:2]比例范围内
  • [0.5,0) 即图片处于[1:2 ~ 1:∞]比例范围内

2.判断图片最长边是否过边界值

  • [1,0.5625)边界值为:1664 * n (n = 1) ,4990 * n (n=2), 1280*pow(2,n-1)(n>=3)
  • [0.5625,0.5)边界值为:1280 × pow (2,n-1) (n>=1)
  • [0.5,0)边界为:1289*pow(2,n-1)(n>=1)

3.计算压缩图片实际边长值,以第2步计算结果为准,超过某个边界值则:width/pow(2,n-1),height/pow(2,n-1)

4.计算压缩图片的实际文件大小,以第2,3步结果为准,图片比例越大则文件越大

size=(newW*newH)/(width*height)*m

  • [1,0.5625)则width& height 对应1556,4990,1280 *n (n>=3),m对应150,300,300;
  • [0.5625,0.5) 则width=1440,height = 2560,m=200;
  • [0.5,0)则width = 1280,height = 1280/scale,m=500;注:scale为比例值

5.判断第四部的size是否过小

  • [1,0.5625) 则最小size对应60,60,100
  • [0.5626,0.5)则最小size都为100,
  • [0.5,0)则最小size都为100

6.将前面求到的值压缩图片width,height,size 传入压缩流程,压缩图片直到满足以上数值。

算法2

参考:https://blog.csdn.net/a429778435/article/details/80604470

图片尺寸
宽高均 <= 1280,图片尺寸大小保持不变
宽或高 > 1280 && 宽高比 <= 2,取较大值等于1280,较小值等比例压缩
宽或高 > 1280 && 宽高比 > 2 && 宽或高 < 1280,图片尺寸大小保持不变
宽高均 > 1280 && 宽高比 > 2,取较小值等于1280,较大值等比例压缩
注:当宽和高均小于1280,并且宽高比大于2时,微信聊天会话和微信朋友圈的处理不一样。
朋友圈:取较小值等于1280,较大值等比例压缩
聊天会话:取较小值等于800,较大值等比例压缩

图片质量

经过大量的测试,微信的图片压缩质量值 ≈ 0.5

漏洞修复

参考

 允许Traceroute探测

本插件使用Traceroute探测来获取扫描器与远程主机之间的路由信息。攻击者也可以利用这些信息来了解目标网络的网络拓扑。


在防火墙中禁用Time Exceeded类型的ICMP包

Iptales防火墙

sudo iptables -A INPUT -p ICMP --icmp-type time-exceeded -j DROP
sudo iptables -A OUTPUT -p ICMP --icmp-type time-exceeded -j DROP
sudo service iptables save
sudo service iptables restart

可通过HTTP获取远端WWW服务信息

nginx

配置 server_tokens off

apache

  1. ServerSignature off;  
  2. ServerToken Prod;  

php

配置 expose_php off https://www.php.net/manual/zh/ini.core.php#ini.expose-php

目标主机rpcinfo -p信息泄露

检测到远端RPCBIND/PORTMAP正在运行中(CVE-1999-0632)

探测到SSH服务器支持的算法

无法处理。ssh协议协商过程就是服务端要返回其支持的算法列表。

SSH版本信息可被获取

无法处理。sshd_config中的Banner项只是ssh主机前输出的信息,源码处理机制就是telnet其端口就会返回版本信息。

Ubuntu下Wireshark普通权限不足之解决方案

参考https://blog.csdn.net/wilsonpeng3/article/details/47209915

安装后打开wireshark 提示权限不足消息:

Couldn’t run /usr/bin/dumpcap in child process: Permission denied

解决方案

~$ sudo groupadd wireshark
groupadd: group 'wireshark' already exists
~$ sudo usermod -a -G wireshark you-user-name
~$ newgrp wireshark
~$ sudo chgrp wireshark /usr/bin/dumpcap
~$ sudo chmod 754 /usr/bin/dumpcap
~$ sudo setcap cap_net_raw,cap_net_admin=eip /usr/bin/dumpcap

10x程序员工作法总结

本文为极客时间专栏总结

以终为始

概述:确定好最终目标(要看到真正的目标).不要把别人交代的工作当成最终目标.what are we going?

发现和规划

人类创造事物都需要经过两次,第一次是在头脑中的创造,也就是智力(想象)创造(Mental/First Creation),第二次才是付诸实践,也就是实际(物理)构建(Physical/Second Creation)

软件开发流程

软件开发中的终,做一个对用户有价值的软件,梳理完整的开发发布流程,提前预演发现潜在问题

DoD完成的定义(Definition)

任务分解

概述:将复杂的(庞大的)任务,拆解成一个个可执行任务,工作分解得越细致,越容易掌控工作,软件开发中的模块化,组件化就是利用了分解的思想.How can we get there?

沟通反馈

概述:保证与他人沟通,保证各方信息及时交互.减少因为理解偏差造成的工作疏漏.同时保证我们能够准确接受外部信息,及时修正自己的错误.

自动化

概述:将繁琐重复的工作,交给程序以自动化的方式执行,提升执行效率和成功率.

Restful Api 风格规范研究

状态码用http status code 还是 在response body 中自定义code

列举总结一下各大厂的API的设计风格

总结

  • 国内资讯类大厂出于兼容性考虑 以及杀毒软件和安全浏览器 拦截404 页面 等并未采用REST API
  • 业务复杂度高的开放平台也未采用Rest API 如支付宝,微信,微博
  • 国外API多采用REST API 包括很多框架的设计(PHP Laravel)

百度手机站

jsonp http status code 200

百度PC站

jsonp ,收集搜索数据接口 http status code 200

今日头条PC

json,使用message区分状态 http status code 200

今日头条手机站

json http status code 200 has_more 区分

新浪微博PC

json http status code 200 直接返回html

微博手机站

Google手机站

restful api

极光推送

RestFul API HTTP STATUS CODE + Response Body 自定义CODE

GitHub

Restful API https://developer.github.com/v3/#client-errors

个人结论

遵守RFC规范,遵守业内标准,融入生态,工业技术是要标准化的。

更详细的论述看左耳朵耗子的文章 “一把梭: REST API 全用 POST”

应用案例

laravel框架默认的错误信息返回风格

去掉最外层data数据包裹 文档

参考