arrange end
404
OS/linux/command.md
Normal file
@ -0,0 +1,404 @@
|
|||||||
|
# 基础命令
|
||||||
|
> sudo
|
||||||
|
> > 配置文件/etc/sudoers 使用visudo进行编辑
|
||||||
|
+ -u # 指定用户
|
||||||
|
|
||||||
|
> pwd
|
||||||
|
|
||||||
|
> cd
|
||||||
|
|
||||||
|
> ls
|
||||||
|
> > 列出目录下所有内容
|
||||||
|
+ -F # 在文件名后加提示符 '/' '*' '@'
|
||||||
|
+ -a # 显示隐藏文件
|
||||||
|
+ -l # 列出文件信息
|
||||||
|
+ -d # 目录
|
||||||
|
+ -h # 将文件大小输出为易读的格式
|
||||||
|
+ -s # 在行首显示(大小)?
|
||||||
|
+ -i # inode
|
||||||
|
|
||||||
|
|
||||||
|
# 文件目录操作管理
|
||||||
|
> cat
|
||||||
|
> >
|
||||||
|
+ -n # 显示行号
|
||||||
|
|
||||||
|
> less
|
||||||
|
|
||||||
|
> od
|
||||||
|
> > 查看非纯文本
|
||||||
|
+ -t # 类型 a, d, f, o, x
|
||||||
|
|
||||||
|
> grep
|
||||||
|
> > 文件字符串匹配
|
||||||
|
+ -A <n> # 后续n行
|
||||||
|
+ -B <n> # 前n行
|
||||||
|
+ -n # 显示行号
|
||||||
|
+ -v # 反向选择
|
||||||
|
+ -E 'o1|o2|o3' # 多匹配
|
||||||
|
|
||||||
|
> wc
|
||||||
|
> > 统计
|
||||||
|
+ -l 行数
|
||||||
|
+ -m 字符
|
||||||
|
+ -w
|
||||||
|
|
||||||
|
> mkdir
|
||||||
|
|
||||||
|
> touch
|
||||||
|
|
||||||
|
> mv
|
||||||
|
> >
|
||||||
|
+ -i # 覆盖时警告
|
||||||
|
+ -b # 重合加~
|
||||||
|
|
||||||
|
> cp
|
||||||
|
> > copy
|
||||||
|
+ -i # 覆盖时警告
|
||||||
|
+ -b # 重合加~
|
||||||
|
+ -u # 仅复制更新
|
||||||
|
+ -v # 详细显示
|
||||||
|
+ -r # 目录
|
||||||
|
|
||||||
|
> rm
|
||||||
|
> >
|
||||||
|
+ -i # 覆盖时警告
|
||||||
|
+ -r # 目录
|
||||||
|
+ -f # 强制
|
||||||
|
|
||||||
|
> chown
|
||||||
|
> > 所有权
|
||||||
|
+ -R # 同时更改所有子目录
|
||||||
|
|
||||||
|
> chmod
|
||||||
|
> > 权限修改
|
||||||
|
+ -R # 同时更改所有子目录
|
||||||
|
```bash
|
||||||
|
SUID 4
|
||||||
|
执行二进制文件时,权限提升为文件所有者
|
||||||
|
|
||||||
|
SGID 2
|
||||||
|
在此权限下的目录进入后,有效用户组变为所有组
|
||||||
|
|
||||||
|
SBIT 1
|
||||||
|
在此权限下的文件夹里创建文件,仅有root与属主有权操作
|
||||||
|
```
|
||||||
|
|
||||||
|
> file
|
||||||
|
> > 观察文件类型
|
||||||
|
+ -i 查看编码格式
|
||||||
|
+ -z 查看压缩格式
|
||||||
|
+ -b 查看文件的系统架构
|
||||||
|
+ -p 详细信息
|
||||||
|
|
||||||
|
> umark
|
||||||
|
> > 设置默认权限,默认是拿掉权限
|
||||||
|
|
||||||
|
> ln
|
||||||
|
> > 链接(硬)
|
||||||
|
+ -s # 符号链接(软)
|
||||||
|
|
||||||
|
> diff
|
||||||
|
> > 比较文件
|
||||||
|
+ -b # 忽略空格
|
||||||
|
+ -i # 忽略大小写
|
||||||
|
+ -B # 忽略空白行
|
||||||
|
|
||||||
|
> patch
|
||||||
|
> > 补丁制作
|
||||||
|
> > example
|
||||||
|
```bash
|
||||||
|
diff -Naur <oldfile> <newfile> > <file.patch> # -p[n] 拿掉路径中的/
|
||||||
|
patch -p<n> < <file.patch> # 制作
|
||||||
|
patch -p<n>-R < <file.patch> # 还原
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
# 文件查找
|
||||||
|
> find
|
||||||
|
> > find [OPTION] [path] [expression]
|
||||||
|
+ -name [filename] # 指定文件名
|
||||||
|
+ -print # 打印结果在终端
|
||||||
|
+ -type [type] # 指定类型
|
||||||
|
+ -atime <+-n> # n天前使用的文件
|
||||||
|
+ -mtime <+-n> # n天前修改的文件
|
||||||
|
> > example
|
||||||
|
+ find /usr/bin -name zip -print
|
||||||
|
|
||||||
|
> locate
|
||||||
|
|
||||||
|
> whereis
|
||||||
|
> > 找命令文件
|
||||||
|
|
||||||
|
> which
|
||||||
|
> > 找PATH
|
||||||
|
+ -a # 全部列出
|
||||||
|
> whoami
|
||||||
|
|
||||||
|
> uname
|
||||||
|
> > 查看系统版本信息
|
||||||
|
+ -a 全部信息
|
||||||
|
|
||||||
|
|
||||||
|
# 文件压缩
|
||||||
|
> gzip
|
||||||
|
> >
|
||||||
|
+ -d # 解压
|
||||||
|
+ -l # 查看压缩效果
|
||||||
|
|
||||||
|
> bzip2
|
||||||
|
> >
|
||||||
|
+ -d # 解压
|
||||||
|
+ -l # 查看压缩效果
|
||||||
|
|
||||||
|
> xz
|
||||||
|
> >
|
||||||
|
+ -z # 压缩
|
||||||
|
+ -d # 解压
|
||||||
|
+ -l # 查看压缩效果
|
||||||
|
+ -k # 保留压缩原文件
|
||||||
|
+ -<number> # 压缩等级
|
||||||
|
+ -T <n> # 使用多个线程
|
||||||
|
+ -v # 显示详细过程
|
||||||
|
|
||||||
|
> tar
|
||||||
|
> > 文件打包
|
||||||
|
+ -c # 创建
|
||||||
|
+ -x # 解开
|
||||||
|
+ -v # 显示详细过程
|
||||||
|
+ -f <file> # 指定文件名
|
||||||
|
+ -z # 调用gzip
|
||||||
|
+ -j # 调用bzip2
|
||||||
|
+ -J # 调用xz
|
||||||
|
> > example
|
||||||
|
+ tar -cvjf shell.tar.bz2 shell/
|
||||||
|
|
||||||
|
> dd
|
||||||
|
> >
|
||||||
|
+ if # input file/device
|
||||||
|
+ of # output file/device
|
||||||
|
+ bs # one black size
|
||||||
|
+ count # *bs
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 磁盘
|
||||||
|
> mount
|
||||||
|
> > 挂载文件系统
|
||||||
|
+ -r # 只读
|
||||||
|
+ -o <loop> # 特殊设备
|
||||||
|
> > /etc/fstab 配置文件
|
||||||
|
+ auto # 开机自动挂载
|
||||||
|
+ noauto # 不自动挂载
|
||||||
|
+ ro # read only
|
||||||
|
+ rw # read and write
|
||||||
|
+ user # 任意用户可挂载
|
||||||
|
> > example
|
||||||
|
+ [设备/UUID] [挂载点] [文件系统] [参数] 0 0
|
||||||
|
|
||||||
|
> umount
|
||||||
|
> > 卸载文件系统
|
||||||
|
|
||||||
|
> df
|
||||||
|
> > 观察磁盘使用情况
|
||||||
|
> > example
|
||||||
|
+ df -hT
|
||||||
|
|
||||||
|
> sync
|
||||||
|
|
||||||
|
> smartctl
|
||||||
|
> > 查看硬盘状态参数
|
||||||
|
-a 全部参数
|
||||||
|
-H 是否正常
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 用户
|
||||||
|
> useradd
|
||||||
|
> >
|
||||||
|
+ -m # 同时建立主目录
|
||||||
|
+ -g # 指定用户组
|
||||||
|
+ -s # 指定shell
|
||||||
|
|
||||||
|
> groupadd
|
||||||
|
|
||||||
|
> passwd
|
||||||
|
|
||||||
|
> userdel
|
||||||
|
> >
|
||||||
|
+ -r # 删除主目录
|
||||||
|
|
||||||
|
> usermod
|
||||||
|
> >
|
||||||
|
+ -d # 修改主目录
|
||||||
|
+ -e <MM/DD/YY># 修改账号有效期
|
||||||
|
+ -s # 修改shell
|
||||||
|
|
||||||
|
> id
|
||||||
|
> > 查看用户信息
|
||||||
|
|
||||||
|
> /etc/passwd
|
||||||
|
> > example
|
||||||
|
+ 登录名:口令:UID:GID:x信息:主目录:shell
|
||||||
|
|
||||||
|
> /etc/group
|
||||||
|
> > example
|
||||||
|
+ 组名:组口令(一般无):GID:user1,user2,user3
|
||||||
|
|
||||||
|
### 用户所有组是passwd和groups的并集
|
||||||
|
|
||||||
|
> newgrp
|
||||||
|
> > 切换有效用户组
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 进程
|
||||||
|
> ps
|
||||||
|
> >
|
||||||
|
+ aux
|
||||||
|
|
||||||
|
> top
|
||||||
|
|
||||||
|
> lsop
|
||||||
|
> > 查看占用文件的进程
|
||||||
|
|
||||||
|
> kill
|
||||||
|
> > 发送信号
|
||||||
|
+ -l # 列出所有信号
|
||||||
|
|
||||||
|
> nice renice
|
||||||
|
> > 调整谦让度
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 网络
|
||||||
|
> ip
|
||||||
|
> >
|
||||||
|
|
||||||
|
> ss
|
||||||
|
> > 查看端口开放情况
|
||||||
|
+ -t # tcp
|
||||||
|
+ -u # udp
|
||||||
|
+ -n # 以端口号显示
|
||||||
|
+ -l # 列出正在监听的服务
|
||||||
|
+ -p # + pid
|
||||||
|
+` -r # 路由表
|
||||||
|
> > example
|
||||||
|
+ ss -tlunp
|
||||||
|
|
||||||
|
> ping
|
||||||
|
|
||||||
|
|
||||||
|
# 系统
|
||||||
|
> systemctl
|
||||||
|
> > systemctl [command] [unit]
|
||||||
|
+ start
|
||||||
|
+ stop
|
||||||
|
+ restart
|
||||||
|
+ reload
|
||||||
|
+ enable
|
||||||
|
+ disable
|
||||||
|
+ status
|
||||||
|
+ mask # 强制注销
|
||||||
|
+ unmask
|
||||||
|
> >
|
||||||
|
+ list-units
|
||||||
|
> >
|
||||||
|
+ get-default # 获取目前target
|
||||||
|
+ set-default # 设置默认target
|
||||||
|
+ isolate # 切换target
|
||||||
|
> > >
|
||||||
|
+ poweroff
|
||||||
|
+ reboot
|
||||||
|
+ suspend # 挂起
|
||||||
|
+ hibernate # 休眠
|
||||||
|
+ rescue # 修复
|
||||||
|
|
||||||
|
|
||||||
|
# 硬件
|
||||||
|
> dmidecode
|
||||||
|
> > 获取硬件信息
|
||||||
|
+ -q # 简洁
|
||||||
|
+ -t # 指定查看类型
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 软件包管理
|
||||||
|
> dpkg
|
||||||
|
> > .deb
|
||||||
|
+ -i # 安装
|
||||||
|
+ -l # 查看版本
|
||||||
|
+ -r # 卸载
|
||||||
|
|
||||||
|
> apt
|
||||||
|
> > apt-get
|
||||||
|
> > >
|
||||||
|
+ updata # 更新软件包缓存
|
||||||
|
+ upgrade # 更新已有软件包的最新版本
|
||||||
|
+ install # 下载并安装
|
||||||
|
+ remove # 卸载
|
||||||
|
+ source # 下载源码
|
||||||
|
> > apt-cache
|
||||||
|
> > >
|
||||||
|
+ search # 搜索
|
||||||
|
+ depends # 列出依赖
|
||||||
|
> > 配置源
|
||||||
|
+ /etc/apt/sources.list
|
||||||
|
|
||||||
|
|
||||||
|
# 其他命令
|
||||||
|
# nohup 命令挂机(退出登陆后依然执行)
|
||||||
|
nohup [command] &
|
||||||
|
`screen` 主要用于用户开启多个独立的会话(称为"窗口")在这些会话之间可以自由切换而不会中断已经运行的程序
|
||||||
|
### 主要功能:
|
||||||
|
1. **多会话管理**:可以同时运行多个独立的 shell 会话。
|
||||||
|
2. **会话分离与重连**:可以从一个会话中分离出来,稍后再重新连接到该会话。
|
||||||
|
3. **窗口分割**:在一个 screen 会话中,可以水平或垂直分割窗口,以同时查看和操作多个任务。
|
||||||
|
4. **滚动记录**:可以查看会话的滚动记录,即使之前的输出已经滚出屏幕。
|
||||||
|
5. **复制和粘贴**:在 screen 会话中,可以使用快捷键复制文本并粘贴到其他位置。
|
||||||
|
6. **会话锁定**:可以锁定当前会话,防止他人查看或操作。
|
||||||
|
7. **自动保存会话**:在网络断开或其他异常情况下,screen 可以自动保存当前会话状态。
|
||||||
|
### 基本使用方法:
|
||||||
|
1. **启动一个新的 screen 会话**:
|
||||||
|
screen
|
||||||
|
2. **列出当前的 screen 会话**:
|
||||||
|
screen -ls
|
||||||
|
3. **重新连接到一个已存在的会话**:
|
||||||
|
screen -r [会话ID或名称]
|
||||||
|
4. **分离当前会话**:
|
||||||
|
在 screen 会话中按 `Ctrl-a` 然后按 `d`。
|
||||||
|
5. **在会话中创建新窗口**:
|
||||||
|
在 screen 会话中按 `Ctrl-a` 然后按 `c`。
|
||||||
|
6. **在窗口之间切换**:
|
||||||
|
在 screen 会话中按 `Ctrl-a` 然后按 `n`(下一个窗口)或 `Ctrl-a` 然后按 `p`(上一个窗口)
|
||||||
|
7. **分割窗口**:
|
||||||
|
- 水平分割:在 screen 会话中按 `Ctrl-a` 然后按 `"`(双引号键)。
|
||||||
|
- 垂直分割:在 screen 会话中按 `Ctrl-a` 然后按 `S`。
|
||||||
|
8. **调整分割窗口的大小**:
|
||||||
|
- 增加/减少水平大小:在 screen 会话中按 `Ctrl-a` 然后按方向键。
|
||||||
|
- 增加/减少垂直大小:在 screen 会话中按 `Ctrl-a` 然后按 `Shift` 加上方向键。
|
||||||
|
9. **退出 screen 会话**:
|
||||||
|
- 关闭当前窗口:在 screen 会话中按 `Ctrl-a` 然后按 `k`。
|
||||||
|
- 退出所有窗口并结束会话:在 screen 会话中按 `Ctrl-a` 然后按 `\`。
|
||||||
|
10. **锁定当前会话**:
|
||||||
|
在 screen 会话中按 `Ctrl-a` 然后按 `x`。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# ulimit
|
||||||
|
查看和修改进程运行资源限制
|
||||||
|
-H/S # 设置/显示 软/硬 限制
|
||||||
|
-a # 显示所有
|
||||||
|
-t # cpu time
|
||||||
|
-f # file size
|
||||||
|
-s # stack size
|
||||||
|
-c # core file size
|
||||||
|
-m # memory size
|
||||||
|
-l # lock memory size
|
||||||
|
-p # user processes
|
||||||
|
-n # open file
|
||||||
|
|
||||||
|
#ulimit -Ht 3600
|
72
OS/linux/knowledge/FileSystem/struct.md
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
# /
|
||||||
|
根目录
|
||||||
|
|
||||||
|
# /bin
|
||||||
|
存放基本的用户命令和系统命令
|
||||||
|
|
||||||
|
# /sbin
|
||||||
|
系统管理员用的系统命令
|
||||||
|
|
||||||
|
# /boot
|
||||||
|
启动所需的内核等
|
||||||
|
|
||||||
|
# /dev
|
||||||
|
设备文件
|
||||||
|
|
||||||
|
# /etc
|
||||||
|
系统配置文件
|
||||||
|
|
||||||
|
# /home
|
||||||
|
用户家目录
|
||||||
|
|
||||||
|
# /lib
|
||||||
|
系统库
|
||||||
|
|
||||||
|
# /media
|
||||||
|
挂载可移动介质
|
||||||
|
|
||||||
|
# /mnt
|
||||||
|
临时挂载文件系统
|
||||||
|
|
||||||
|
# /proc
|
||||||
|
虚拟文件系统
|
||||||
|
|
||||||
|
# /root
|
||||||
|
root家目录
|
||||||
|
|
||||||
|
# /tmp
|
||||||
|
临时文件
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# /opt
|
||||||
|
存放可选的第三方软件
|
||||||
|
|
||||||
|
# /usr 存放不经常变动的程序和文件
|
||||||
|
> /usr/bin
|
||||||
|
用户级程序
|
||||||
|
> /usr/sbin
|
||||||
|
|
||||||
|
> /usr/include
|
||||||
|
|
||||||
|
> /usr/lib
|
||||||
|
|
||||||
|
> /usr/share
|
||||||
|
共享数据文件
|
||||||
|
|
||||||
|
> /usr/src
|
||||||
|
存放源码
|
||||||
|
|
||||||
|
# /var 存放经常变动的文件
|
||||||
|
> /var/log
|
||||||
|
|
||||||
|
> /var/mail
|
||||||
|
|
||||||
|
> /var/run
|
||||||
|
系统运行的临时文件
|
||||||
|
|
||||||
|
# /run
|
||||||
|
类似 /var/run 但是重启时不会清空
|
||||||
|
|
||||||
|
# /sys
|
||||||
|
虚拟文件系统,包含硬件信息,比 /proc 更易访问
|
240
OS/linux/knowledge/elf.md
Normal file
@ -0,0 +1,240 @@
|
|||||||
|
# [ELF文件格式]
|
||||||
|
|
||||||
|
ELF是程序文件的一种类型,它并非由Linux研发,但Linux采用这种类型管理程序文件,具体又分为以下四类
|
||||||
|
|
||||||
|
1. 可执行文件,可以自己在操作系统中执行的程序。
|
||||||
|
|
||||||
|
2. 可重定向文件,不能自己在操作系统中执行的程序,其只有程序本身的数据,没有操作系统识别其各种属性以及辅助执行的数据,需要使用连接器添加属性信息、以及辅助执行代码制作为可执行文件才能在操作系统中执行,或用于被其它程序调用,与其它程序一起组合为可执行文件。
|
||||||
|
|
||||||
|
3. 动态连接库文件,类似可重定向文件,不能自己执行,需要被其它程序调用执行,但是在执行期间与其组合为一体
|
||||||
|
|
||||||
|
4. 核心转储文件,进程执行出错后操作系统将其终止执行,同时将进程在内存中的数据保存一份到辅存,用户可以读取核心转储文件查询进程终止前的执行状态与终止原因。
|
||||||
|
__静态连接库不归类于ELF文件__
|
||||||
|
|
||||||
|
## ELF文件内的数据可以分为四类:
|
||||||
|
|
||||||
|
1. 文件头,文件内容起始数据,用于说明文件类型、文件属性。
|
||||||
|
|
||||||
|
2. 程序节属性表,同节属性表,但只用于存储指令数据节、指令执行相关节的属性
|
||||||
|
|
||||||
|
3. 节,英文名为section,也有人称为段,程序的指令数据、数学数据、运行相关属性数据会按作用分为多组,每一组使用一个节存储。
|
||||||
|
|
||||||
|
4. 节属性表,是一个元素为结构体的数组,每个元素存储一个节的属性信息。
|
||||||
|
|
||||||
|
### 文件头
|
||||||
|
文件头使用一个结构体定义,以64位ELF文件为例,文件头原型如下:
|
||||||
|
```c
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned char e_ident[16];
|
||||||
|
//前4个字节数据分别为:7f 45 4c 46,第一个字节为删除键编码、后三个字节为ELF字母的编码,表示这是ELF文件
|
||||||
|
//第5个字节说明ELF文件运行在32位处理器还是64位处理器,值为1表示32位,值为2表示64位
|
||||||
|
//第6个字节说明数学数据使用的字节序,值为1表示小端序,值为2表示大端序
|
||||||
|
//第7个字节说明ELF文件的版本,目前只能设置为1
|
||||||
|
//第8个字节指定程序使用的ABI的类型,通常设置为0
|
||||||
|
//第9个字节指定程序使用的ABI的版本,通常设置为0
|
||||||
|
//第10-16字节保留不用,全部赋值为0
|
||||||
|
|
||||||
|
u16 e_type; //指定ELF文件的具体类型,值为1-4,1表示可重定向文件,2表示可执行文件,3表示动态连接库,4表示核心转储文件
|
||||||
|
u16 e_machine; //指定程序使用的CPU类型,值为62表示64位X86处理器,值为40表示32位ARM处理器,值为183表示64位ARM处理器
|
||||||
|
u32 e_version; //指定ELF文件的版本,目前只有一个版本,值固定为1
|
||||||
|
|
||||||
|
u64 e_entry; //指定程序执行入口虚拟地址,虚拟地址从0x400000开始算起,若为可重定向文件、动态连接库,则此值为0
|
||||||
|
u64 e_phoff; //指定程序节属性表的文件内部地址,文件内部地址从0开始分配,文件头占用最开始的地址,程序节属性表在之后,若e_phoff为0表示不包含程序节属性表
|
||||||
|
u64 e_shoff; //指定节属性表的文件内部地址,若为0表示不包含节属性表
|
||||||
|
|
||||||
|
u32 e_flags; //程序运行在特殊处理器中时使用此数据设置某些信息,运行在x86处理器中时此数据设置为0
|
||||||
|
|
||||||
|
u16 e_ehsize; //文件头的长度,以字节为单位
|
||||||
|
|
||||||
|
u16 e_phentsize; //程序节属性表的元素长度,以字节为单位
|
||||||
|
u16 e_phnum; //程序节属性表的元素数量
|
||||||
|
|
||||||
|
u16 e_shentsize; //节属性表的元素长度,以字节为单位
|
||||||
|
u16 e_shnum; //节属性表的元素数量
|
||||||
|
|
||||||
|
u16 e_shstrndx; //指定节属性表中哪个元素存储shstrtab节信息,值为元素下标
|
||||||
|
} Elf64_Ehdr;
|
||||||
|
```
|
||||||
|
+ e_ident的第8-9个字节设置ABI信息,ABI全称为Application Binary Interface,中文名为应用程序二进制接口,它是一组规则的名称,是操作系统为程序制定的运行规则,比如:多字节数据排序方式、函数调用时参数如何传递、函数返回值如何存储、系统调用使用规则、异常功能使用规则,CPU在设计时会为了兼容ABI的某些规则进行优化,提升程序运行速度
|
||||||
|
|
||||||
|
#### 一个 x86-64 ELF 可执行文件的文件头
|
||||||
|
```
|
||||||
|
7F 45 4C 46 02 01 01 00 00 00 00 00 00 00 00 00 //e_ident
|
||||||
|
02 00 3E 00 01 00 00 00 //e_type - e_version
|
||||||
|
40 10 40 00 00 00 00 00 //e_entry
|
||||||
|
40 00 00 00 00 00 00 00 //e_phoff
|
||||||
|
18 39 00 00 00 00 00 00 //e_shoff
|
||||||
|
00 00 00 00 40 00 38 00 //e_flags - e_phentsize
|
||||||
|
0B 00 40 00 1D 00 1C 00 //e_phnum - e_shstrndx
|
||||||
|
```
|
||||||
|
|
||||||
|
### 程序节属性表
|
||||||
|
+ 程序节属性表紧邻文件头,是一个数组,元素为结构体,专用于存储程序节的属性
|
||||||
|
```c
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
u32 p_type; //指定节的类型
|
||||||
|
u32 p_flags; //设置节的访问权限,最低位设置执行权限、第2位设置写权限、第3位设置读权限,对应位设置为1表示有此权限,指令节设置为可执行,全局变量节设置为可读可写,全局常量节设置为只读
|
||||||
|
|
||||||
|
u64 p_offset; //节的文件内部地址
|
||||||
|
u64 p_vaddr; //节的虚拟地址
|
||||||
|
u64 p_paddr; //节的内存物理地址,某些特殊操作系统需要使用,在linux中不使用此数据
|
||||||
|
|
||||||
|
u64 p_filesz; //ELF文件在辅存中存储时,此节的长度
|
||||||
|
u64 p_memsz; //ELF文件读取到内存中时,此节的长度,有些节只在程序执行时才会存储数据,比如.bss节,这种节只在内存中分配存储空间
|
||||||
|
u64 p_align; //节的内存地址对齐值,若值为0或1等同于无对齐要求
|
||||||
|
}Elf64_Phdr;
|
||||||
|
```
|
||||||
|
```
|
||||||
|
06 00 00 00 04 00 00 00 //p_type、p_flags
|
||||||
|
40 00 00 00 00 00 00 00 //p_offset
|
||||||
|
40 00 40 00 00 00 00 00 //p_vaddr
|
||||||
|
40 00 40 00 00 00 00 00 //p_paddr
|
||||||
|
68 02 00 00 00 00 00 00 //p_filesz
|
||||||
|
68 02 00 00 00 00 00 00 //p_memsz
|
||||||
|
08 00 00 00 00 00 00 00 //p_align
|
||||||
|
```
|
||||||
|
|
||||||
|
### 节
|
||||||
|
|
||||||
|
__动态连接相关__
|
||||||
|
```
|
||||||
|
.interp,存储动态库加载器的路径,是一个字符串,ELF可执行文件才有此节。
|
||||||
|
|
||||||
|
.dynsym(Dynamic Symbol),存储动态库全局成员的属性,类似.strtab。
|
||||||
|
|
||||||
|
.dynstr(Dynamic String),存储动态库全局成员的名称,每个名称都是以空字符结尾的字符串,同时此节的第一个字节也定义为空字符。
|
||||||
|
```
|
||||||
|
__指令数据节__
|
||||||
|
```
|
||||||
|
.init,存储程序执行入口指令,用于程序执行前的基础初始化工作,代码由编译器自动生成,之后跳转到.text节执行,存储指令数据的节会被操作系统设置为只读。
|
||||||
|
|
||||||
|
.plt(procedure linkage table),调用动态库内数据相关,内部是由编译器生成的多个汇编代码模块。
|
||||||
|
|
||||||
|
.text,存储程序主体功能代码,程序执行前复杂的初始化工作代码在这里(编译器生成),用户自己编写的代码也存储在这里。
|
||||||
|
|
||||||
|
.fini,存储程序终止时执行的相关代码,代码由编译器生成
|
||||||
|
```
|
||||||
|
__数学数据节__
|
||||||
|
```
|
||||||
|
.rodata,存储全局常量,此节分配的内存页会被操作系统设置为只读。
|
||||||
|
|
||||||
|
.init_array,存储一组函数地址,这些函数会在main函数之前执行。
|
||||||
|
|
||||||
|
.fini_array,存储一组函数地址,这些函数会在main函数之后执行。
|
||||||
|
|
||||||
|
.dynamic,存储操作系统将程序加载到内存执行时需要使用的某些信息,比如程序需要使用哪些动态库、某些节的虚拟地址,具体数据的含义可使用 readelf -d 命令查看。
|
||||||
|
|
||||||
|
.got(global offset table),主要存储glibc两个函数的地址:__gmon_start__、__libc_start_main,此地址在ELF文件中存储0,程序执行时操作系统将gilbc读取到内存,之后将函数的具体地址写入.got。
|
||||||
|
|
||||||
|
.data,存储定义时已赋值的全局变量。
|
||||||
|
|
||||||
|
.bss,存储定义时未赋值的全局变量,编译后的文件此节不占用存储空间,程序读取到内存执行时才会为此节分配存储空间,此节占用的内存单元会全部设置为0,定义全局变量不赋值的话初始值为0
|
||||||
|
```
|
||||||
|
__编译器相关__
|
||||||
|
```
|
||||||
|
.comment,存储编译器版本信息,内部是一个字符串
|
||||||
|
```
|
||||||
|
__调试相关__
|
||||||
|
```
|
||||||
|
.debug,存储调试程序时需要的相关信息,供调试器使用,比如数据的类型、指令数据对应的高级语言源代码行号,使用gcc编译程序时添加 -g 参数会生成此节。
|
||||||
|
```
|
||||||
|
|
||||||
|
__全局成员相关__
|
||||||
|
```
|
||||||
|
.symtab(symbol table),程序中的全局变量、全局常量、函数这三者统称为symbol,有人将其翻译为符号,鉴于这种翻译完全不合理,这里将其称为全局成员,.symtab节用于存储所有全局成员的属性信息,比如数据类型、数据长度、成员名称(实际存储的是数据名在.strtab节的位置)、成员是否可被外部程序调用,每个全局成员的属性使用一个Elf64_Sym结构体存储,所有的Elf64_Sym结构体组成一个数组,这个数组就是.symtab节。
|
||||||
|
|
||||||
|
.strtab(string table),存储全局成员(symbol)的名称,对程序进行调试和反汇编时看见的数据名由此节记录,使用gcc编译程序时可以添加-s参数不保留这些数据名。对于C语言程序,此节记录的是数据名原型,对于C++程序,此节记录的并非原始数据名,因为C++支持函数重载、符号重载、虚拟类型、命名空间,导致多个数据可以同名,编译器会在原始数据名的前后分别添加随机字符从而区分同名数据,另外类成员、命名空间成员还会包含类名、命名空间名
|
||||||
|
```
|
||||||
|
__节名相关__
|
||||||
|
```
|
||||||
|
.shstrtab,存储其它节的名称,为节设置名称是编译器的工作,使用gcc编译程序时添加-s参数将不会生成节名称
|
||||||
|
```
|
||||||
|
|
||||||
|
### 节属性表
|
||||||
|
`程序节之外的节使用Elf64_Shdr结构体存储其属性,每个节的属性称为 section headers,简称sh,所有的 section headers 组合为节属性表。`
|
||||||
|
```c
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
u32 sh_name; //存储本节的名称在shstrtab节中的位置,若为0则表示此节没有名称
|
||||||
|
|
||||||
|
u32 sh_type; //节的类型,常用值如下:
|
||||||
|
//SHT_NULL,值为0,无效节
|
||||||
|
//SHT_PROGBITS,值为1,存储程序运行所用数据的节,比如.text、.data、.rodata,不包含.bss
|
||||||
|
//SHT_SYMTAB,值为2,.symtab节
|
||||||
|
//SHT_STRTAB,值为3,字符串表,包括 .strtab .shstrtab .dynstr
|
||||||
|
//SHT_RELA,值为4,.rela节
|
||||||
|
//SHT_HASH,值为5,.hash节
|
||||||
|
//SHT_DYNAMIC,值为6,.dynamic节
|
||||||
|
//SHT_NOTE,值为7,此节包含一些注释信息
|
||||||
|
//SHT_NOBITS,值为8,此节不在ELF文件中,而是在程序执行期间分配内存空间,比如.bss
|
||||||
|
//SHT_REL,值为9,.rel节
|
||||||
|
//SHT_SHLIB,值为10,保留节,具体含义未定义
|
||||||
|
//SHT_DYNSYM,值为11,.dynsym节
|
||||||
|
|
||||||
|
u64 sh_flags; //节的访问权限
|
||||||
|
|
||||||
|
u64 sh_addr; //节的虚拟地址,若为0则程序执行时此节不会读取到内存中,因为这些节只起辅助作用
|
||||||
|
u64 sh_offset; //节的文件内部地址
|
||||||
|
u64 sh_size; //节的长度,单位为字节
|
||||||
|
|
||||||
|
u32 sh_link; //节属性表中另一个元素的下标,连接器有时需要知道两个节的联系,若不需要与另一个节有关联则设置为0
|
||||||
|
u32 sh_info; //附加信息
|
||||||
|
u64 sh_addralign; //节的内存地址对齐值,若值为0或1则表示无对齐要求
|
||||||
|
u64 sh_entsize; //有些节的内容是一个数组,此成员存储数组元素的长度,若节的内容不是数组则设置为0
|
||||||
|
} Elf64_Shdr;
|
||||||
|
```
|
||||||
|
```
|
||||||
|
// 一个 x86-64 ELF 可执行文件的 .shstrtab 节属性信息:
|
||||||
|
|
||||||
|
11 00 00 00 03 00 00 00 //sh_name - sh_type
|
||||||
|
00 00 00 00 00 00 00 00 //sh_flags
|
||||||
|
00 00 00 00 00 00 00 00 //sh_addr
|
||||||
|
2d 38 00 00 00 00 00 00 //sh_offset
|
||||||
|
03 01 00 00 00 00 00 00 //sh_size
|
||||||
|
00 00 00 00 00 00 00 00 //sh_link - sh_info
|
||||||
|
01 00 00 00 00 00 00 00 //sh_addralign
|
||||||
|
00 00 00 00 00 00 00 00 //sh_entsize
|
||||||
|
```
|
||||||
|
|
||||||
|
## RIP相对寻址
|
||||||
|
`在x86处理器中,指令使用32位内存地址读写内存,在x86-64处理器中,指令使用64位内存地址读写内存,64位处理器的mov指令使用直接内存寻址的方式读写内存数据时,若使用立即数存储要操作的内存地址则指令长度会超标(指令操作码 + 8字节内存地址 + 寄存器编号或4字节立即数),为此x86-64新增了一种内存寻址方式,称为RIP相对寻址,其让RIP寄存器增加一个值得出要操作的内存地址,就像跳转指令使用IP寄存器加一个立即数得出要跳转到的地址一样`
|
||||||
|
|
||||||
|
`RIP相对寻址用于程序的全局数据寻址,局部数据在栈中存储,栈空间数据不使用rip相对寻址,而是使用rsp、rbp确定要操作的地址`
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include <stdio.h>
|
||||||
|
int a = 1;
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
a = 9;
|
||||||
|
printf("%d\n", a);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
```asm
|
||||||
|
0000000000401122 <main>:
|
||||||
|
401122: 55 push rbp
|
||||||
|
401123: 48 89 e5 mov rbp,rsp
|
||||||
|
401126: c7 05 00 2f 00 00 09 00 00 00 mov DWORD PTR [rip+0x2f00],0x9 ;调用变量a(地址404030),rip现值 = 0x401130,0x401130 + 0x2f00 = 0x404030
|
||||||
|
401130: 8b 05 fa 2e 00 00 mov eax,DWORD PTR [rip+0x2efa] ;变量a写入eax
|
||||||
|
401136: 89 c6 mov esi,eax
|
||||||
|
401138: bf 04 20 40 00 mov edi,0x402004
|
||||||
|
40113d: b8 00 00 00 00 mov eax,0x0
|
||||||
|
401142: e8 e9 fe ff ff call 401030 ;调用printf,rip加-0x117补码,向前跳转到0x401030
|
||||||
|
401147: b8 00 00 00 00 mov eax,0x0
|
||||||
|
40114c: 5d pop rbp
|
||||||
|
40114d: c3 ret
|
||||||
|
|
||||||
|
Contents of section .data:
|
||||||
|
404020 00000000 00000000 00000000 00000000
|
||||||
|
404030 01000000
|
||||||
|
```
|
||||||
|
地址401126处的mov指令长度10字节,分别如下:
|
||||||
|
|
||||||
|
操作码,2字节,值为 05 c7。
|
||||||
|
地址码1,4字节,存储rip要加的数据,定位到操作的内存单元,值为 00 00 2f 00。
|
||||||
|
地址码2,4字节,存储要写入的立即数,值为 00 00 00 09。
|
||||||
|
rip与一个4字节有符号数相加,总共可以寻址约4GB内存空间,前后各2GB。
|
24
OS/linux/knowledge/keybroad.md
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# linux键盘高级操作技巧
|
||||||
|
> 光标移动
|
||||||
|
+ C a # 到行首
|
||||||
|
+ C e # 到行末
|
||||||
|
+ C f # 下一个字符
|
||||||
|
+ C b # 上一个字符
|
||||||
|
+ C l # clean
|
||||||
|
+ A f # 下一个词
|
||||||
|
+ A b # 上一个词
|
||||||
|
|
||||||
|
> 文本修改
|
||||||
|
+ C t # 与上一个字符互换
|
||||||
|
+ A t # 与上一个词互换
|
||||||
|
|
||||||
|
> 批量处理
|
||||||
|
+ C k # 剪切到行尾
|
||||||
|
+ C u # 剪切到行首
|
||||||
|
+ C y # 粘贴
|
||||||
|
|
||||||
|
> 命令
|
||||||
|
+ C p # 上一个命令
|
||||||
|
+ C n # 下一个命令
|
||||||
|
+ C j # 复制
|
||||||
|
+ C o # 执行当前项,并移到下一项
|
@ -2,4 +2,5 @@ cmd //cmd
|
|||||||
dxdiag //电脑配置
|
dxdiag //电脑配置
|
||||||
mrt //清理恶意软件
|
mrt //清理恶意软件
|
||||||
cleanmgr //清理磁盘
|
cleanmgr //清理磁盘
|
||||||
regedit //使用注册表
|
regedit //使用注册表
|
||||||
|
shell:RecycleBinFolder
|
@ -13,6 +13,7 @@ ipconfig /flushdns // 清空DNS缓存
|
|||||||
nslookup //查询任何一台机器的IP和对应的域名
|
nslookup //查询任何一台机器的IP和对应的域名
|
||||||
netstat //显示活动的TCP连接,计算机侦听的端口,以太网统计信息,IP路由表,IPv4统计信息以及IPv6统计信息
|
netstat //显示活动的TCP连接,计算机侦听的端口,以太网统计信息,IP路由表,IPv4统计信息以及IPv6统计信息
|
||||||
powercfg -h off //关闭休眠,可节省C盘空间
|
powercfg -h off //关闭休眠,可节省C盘空间
|
||||||
|
shutdown /r /fw /t 0 // 重启到BIOS
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
windows控制台命令 大集合
|
windows控制台命令 大集合
|
20
OrdinaryHeroChronicles.md
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# 谨以此表,以记平凡的英雄们
|
||||||
|
|
||||||
|
# 华中农业大学学术造假事件发起联合举报的11位学子
|
||||||
|
黄飞若教授学术造假
|
||||||
|
2024年1月16日 11位学生联合举报黄飞若为首的学术造假事件
|
||||||
|
虽螳臂当车吾亦往矣(举报pdf结语)
|
||||||
|
星星之火,可以燎原,把这枚火种,传下去!
|
||||||
|
|
||||||
|
# 雨希不想画画 up 2006/11/9--2024/2/22
|
||||||
|
2024年2月21日下午5点54分,
|
||||||
|
放学后外出吃饭的过程中为救一位小孩被车碾压,次日抢救无效离世
|
||||||
|
被救的小朋友并无生命危险,仅伤到腿
|
||||||
|
雨希以生命为代价救下了这位小朋友
|
||||||
|
|
||||||
|
# 永城市实验高级中学5.14事件全体学生
|
||||||
|
2015年5月14日
|
||||||
|
起因 食堂条件差,且食堂经理殴打买茶叶蛋师娘,校领导不作为
|
||||||
|
学生强烈抗议,打砸食堂
|
||||||
|
事件过后领头学生被叫到校领导办公室处置,学生发起二次冲锋
|
||||||
|
结果 校领导被撤销党内职务,行政撤职处分
|
19
README.md
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
存放计算机类笔记的仓库
|
||||||
|
======================
|
||||||
|
|
||||||
|
## 使用说明以及环境
|
||||||
|
+ 今后我尽量改写成makedown的文本
|
||||||
|
|
||||||
|
|
||||||
|
## 项目结构
|
||||||
|
|
||||||
|
|
||||||
|
## 更新连接
|
||||||
|
|
||||||
|
|
||||||
|
## 历史版本 Histroy
|
||||||
|
|
||||||
|
|
||||||
|
## 作者列表 AUTHORS
|
||||||
|
+ ely
|
||||||
|
|
@ -1,64 +0,0 @@
|
|||||||
// 示例客户端程序
|
|
||||||
// 发送文件到服务端
|
|
||||||
#include <iostream>
|
|
||||||
#include <fstream>
|
|
||||||
#include "tn.h"
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
struct FileStat { //存放文件信息
|
|
||||||
char name[128]; // 文件名
|
|
||||||
size_t fsize = 0, read = 0, ssize = 0;
|
|
||||||
//文件大小 文件已读大小 本次发送大小
|
|
||||||
};
|
|
||||||
|
|
||||||
int pton(char *, const char *);
|
|
||||||
int file_out(TN &, char *); // 传入一个连接和文件路径
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
|
||||||
if(argc != 2) {
|
|
||||||
cout << "Using: ./cli.exe 文件名" << endl;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
TN test1;
|
|
||||||
if(test1.client("127.0.0.1","12345")!=0)
|
|
||||||
return 0;
|
|
||||||
cout << "连接已成功" << endl;
|
|
||||||
cout << file_out(test1, argv[1]) << endl;
|
|
||||||
cout << "连接断开" << endl;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int pton(char *name, const char *path) {
|
|
||||||
int ptr = strlen(path);
|
|
||||||
while(ptr!=0 && path[ptr-1]!='/')
|
|
||||||
ptr--;
|
|
||||||
for(int j=0; ptr<=strlen(path); j++,ptr++)
|
|
||||||
name[j]=path[ptr];
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int file_out(TN &tn, char *path) { // 传入一个连接和文件路径
|
|
||||||
const unsigned int BSIZE = 1024;
|
|
||||||
char buffer[BSIZE];
|
|
||||||
FileStat fs;
|
|
||||||
fstream fin(path, ios::in|ios::binary);
|
|
||||||
pton(fs.name, (const char *)path);
|
|
||||||
fin.seekg(0, ios::end);
|
|
||||||
fs.fsize = fin.tellg();
|
|
||||||
fin.seekg(0, ios::beg);
|
|
||||||
|
|
||||||
// 发送信息
|
|
||||||
if(tn.out((FileStat *)&fs, sizeof(fs))!=0) return 0;
|
|
||||||
if(tn.in((char *)buffer)!=0) return 0; // 接收确认报文
|
|
||||||
|
|
||||||
// 正式发送文件
|
|
||||||
while(fin.good() && fs.fsize>fs.read) {
|
|
||||||
memset(buffer, 0, sizeof(buffer));
|
|
||||||
fs.ssize = (fs.fsize-fs.read)>BSIZE? BSIZE:(fs.fsize-fs.read);
|
|
||||||
fin.read(buffer, fs.ssize);
|
|
||||||
if(tn.out(buffer, fs.ssize)!=0) return -1;
|
|
||||||
fs.read += fs.ssize;
|
|
||||||
}
|
|
||||||
fin.close();
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
main: ser.o cli.o tn.o
|
|
||||||
g++ -o ser.exe ser.o tn.o
|
|
||||||
g++ -o cli.exe cli.o tn.o
|
|
||||||
clear:
|
|
||||||
rm *.o *.exe
|
|
@ -1,110 +0,0 @@
|
|||||||
```cpp
|
|
||||||
#include <iostream>
|
|
||||||
#include <cstring>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <netdb.h>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
```
|
|
||||||
|
|
||||||
# tips
|
|
||||||
+ 所有网络函数失败基本是返回 -1,errno被设置
|
|
||||||
|
|
||||||
# socket
|
|
||||||
|
|
||||||
|
|
||||||
原型: int socket(int domain, int type, int protocol)
|
|
||||||
|
|
||||||
+ domain 协议族
|
|
||||||
\ PF_INET # IPv4 互联网协议族
|
|
||||||
\ PF_INET6 # IPv6 互联网协议族
|
|
||||||
\ PF_LOCAL # 本地通讯地址族
|
|
||||||
|
|
||||||
+ type 数据传输类型
|
|
||||||
\ SOCK_STREAM # 面向连接; 数据不丢失; 数据顺序不错乱; 双向通道;
|
|
||||||
\ SOCK_DGRAM # 无连接; 数据可能丢; 数据可能错乱; 效率高;
|
|
||||||
|
|
||||||
+ protocol 最终使用协议
|
|
||||||
\ IPPROTO_TCP
|
|
||||||
\ IPPROTO_UDP
|
|
||||||
\ 0 # 编译器自动识别
|
|
||||||
|
|
||||||
# 主机字节序和网络字节序
|
|
||||||
|
|
||||||
+ 大端序和小端序 (如果数据大于1B,CPU在内存中存放数据的方式)
|
|
||||||
\ 大端序 低位字节在高位,高位字节在低位
|
|
||||||
\ 小端序 低位字节在低位,高位字节在高位 (INTEL)
|
|
||||||
|
|
||||||
## 字节序不同的系统字节传输数据,可能会出现问题,所以网络字节序约定使用大端序
|
|
||||||
+ c提供了4个库用于主机字节序和网络字节序之间的转换
|
|
||||||
\ uint16_t htons(uint16_t hostshort); // 2字节的整数
|
|
||||||
\ uint32_t htonl(uint32_t hostshort); // 4字节的整数
|
|
||||||
\ uint16_t ntons(uint16_t netshort); // 2字节的整数
|
|
||||||
\ uint32_t ntonl(uint32_t netshort); // 4字节的整数
|
|
||||||
// h host主机
|
|
||||||
// to 转换
|
|
||||||
// n network网络
|
|
||||||
// s short(2byte)
|
|
||||||
// l long(4byte)
|
|
||||||
|
|
||||||
# IP地址和通讯端口
|
|
||||||
+ IPv4(4byte) 端口(2byte)
|
|
||||||
|
|
||||||
# 大小端序的处理
|
|
||||||
+ 在网络编程中数据收发有自动转换,只有sockaddr_in结构成员变量填充数据时,才需要考虑字节序
|
|
||||||
|
|
||||||
# 结构体
|
|
||||||
|
|
||||||
## sockaddr
|
|
||||||
```cpp
|
|
||||||
struct sockaddr { // connect() bind() 都需要
|
|
||||||
unsigned short sa_family; // 协议族
|
|
||||||
unsigned char sa_data[14]; // 14byte的端口和地址
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## sockaddr_in
|
|
||||||
```cpp
|
|
||||||
struct sockaddr { // 为了方便操作,大小与sockaddr相同,可以强制转换
|
|
||||||
unsigned short sin_family; // 协议族
|
|
||||||
unsigned short sin_port; // 2byte端口号
|
|
||||||
//struct in_addr sin_addr; // 4byte地址
|
|
||||||
unsigned int sin_addr; // 4byte地址
|
|
||||||
unsigned char sin_zero[8]; // 保留,长度对齐
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
# gethostbyname函数
|
|
||||||
|
|
||||||
+ 用 域名/主机名/字符串IP 转换成大端序
|
|
||||||
```cpp
|
|
||||||
struct hostent *gethostbyname(const char *name);
|
|
||||||
struct hostent {
|
|
||||||
char *h_name; // 主机名
|
|
||||||
char **h_aliases; // 主机所有别名的字符串数组
|
|
||||||
short h_addrtype; // 主机IP类型,IPv4或IPv6
|
|
||||||
short h_length; // 主机IP长度
|
|
||||||
char **h_addr_list; // 主机IP地址,以网络字节序存储
|
|
||||||
}
|
|
||||||
#define h_addr h_addr_list[0]
|
|
||||||
|
|
||||||
// 转换后,用 memcpy(&servaddr.sin_addr, h->h_addr, h->h_length);
|
|
||||||
```
|
|
||||||
|
|
||||||
# 字符串IP和大端序IP的转换
|
|
||||||
## atoi() 把字符串IP转换成大端序
|
|
||||||
```cpp
|
|
||||||
typedef unsigned int in_addr_t; //4byte大端序IP
|
|
||||||
|
|
||||||
// 字符串转大端序IP,转换后IP赋给sockaddr_in.in_addr.s_addr
|
|
||||||
in_addr_t inet_addr(const char *cp);
|
|
||||||
|
|
||||||
// 字符串转大端序IP,转换后IP赋给sockaddr_in.in_addr
|
|
||||||
int inet_aton(const char *cp, struct in_addr *inp);
|
|
||||||
|
|
||||||
//大转字符串,用于服务端解析IP
|
|
||||||
char *inet_ntoa(struct in_addr in);
|
|
||||||
```
|
|
||||||
|
|
@ -1,61 +0,0 @@
|
|||||||
// 示例服务端程序
|
|
||||||
// 一个可以接收文件的服务端程序
|
|
||||||
#include <iostream>
|
|
||||||
#include <fstream>
|
|
||||||
#include "tn.h"
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
struct FileStat { //存放文件信息
|
|
||||||
char name[128]; // 文件名
|
|
||||||
size_t fsize = 0, read = 0, ssize = 0;
|
|
||||||
//文件大小 文件已读大小 本次发送大小
|
|
||||||
};
|
|
||||||
|
|
||||||
int pton(char *, const char *);
|
|
||||||
int file_in(TN &, char *); // 传入一个连接和文件保存目录
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
|
||||||
if(argc != 2 || (argv[1][strlen(argv[1])-1]!='/')) {
|
|
||||||
cout << "Using: ./ser.exe [PATH]/" << endl;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
TN test1;
|
|
||||||
test1.server("12345", 10);
|
|
||||||
cout << "客户端连接成功" << endl;
|
|
||||||
cout << file_in(test1, argv[1]) << endl;
|
|
||||||
cout << "客户端连接断开" << endl;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int pton(char *name, const char *path) {
|
|
||||||
int ptr = strlen(path);
|
|
||||||
while(ptr!=0 && path[ptr-1]!='/')
|
|
||||||
ptr--;
|
|
||||||
for(int j=0; ptr<=strlen(path); j++,ptr++)
|
|
||||||
name[j]=path[ptr];
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int file_in(TN &tn, char *path) { // 传入一个连接和文件保存目录
|
|
||||||
const unsigned int BSIZE = 1024;
|
|
||||||
char buffer[BSIZE];
|
|
||||||
FileStat fs;
|
|
||||||
fstream fout;
|
|
||||||
memset(buffer, 0, sizeof(buffer));
|
|
||||||
strcpy(buffer, path);
|
|
||||||
if(tn.in((FileStat *)&fs, sizeof(fs))!=0) return 0; // 接收文件信息
|
|
||||||
strcat(buffer, fs.name); // 连接字符串
|
|
||||||
// strcpy(fs.name, buffer);
|
|
||||||
fout.open(buffer, ios::out|ios::trunc|ios::binary); // 打开保存文件
|
|
||||||
if(tn.out((char *)"OK")!=0) return 0; // 发送确认报文
|
|
||||||
|
|
||||||
while(fout.good() && fs.fsize>fs.read) {
|
|
||||||
memset(buffer, 0, sizeof(buffer));
|
|
||||||
fs.ssize = (fs.fsize-fs.read)>BSIZE? BSIZE:(fs.fsize-fs.read);
|
|
||||||
if(tn.in(buffer, fs.ssize)!=0) return -2;
|
|
||||||
fout.write(buffer, fs.ssize);
|
|
||||||
fs.read += fs.ssize;
|
|
||||||
}
|
|
||||||
fout.close();
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,119 +0,0 @@
|
|||||||
#include "tn.h"
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
TN::TN() {
|
|
||||||
iofd = listenfd = 0;
|
|
||||||
}
|
|
||||||
TN::~TN() {
|
|
||||||
close(listenfd); //关闭连接
|
|
||||||
close(iofd); //关闭连接
|
|
||||||
}
|
|
||||||
|
|
||||||
int TN::server(const char *open_port, int connections) {
|
|
||||||
// 创建服务端socket
|
|
||||||
listenfd = socket(AF_INET, SOCK_STREAM, 0);
|
|
||||||
if(listenfd == -1)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
// 向客户端请求连接
|
|
||||||
memset(&servaddr, 0, sizeof(servaddr));
|
|
||||||
servaddr.sin_family = AF_INET;
|
|
||||||
servaddr.sin_addr.s_addr = htons(INADDR_ANY);
|
|
||||||
servaddr.sin_port = htons(atoi(open_port)); //指定连接端口
|
|
||||||
|
|
||||||
// 解决端口重用问题
|
|
||||||
int opt = 1;
|
|
||||||
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof opt);
|
|
||||||
|
|
||||||
// 绑定服务端IP及端口
|
|
||||||
if(bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0)
|
|
||||||
return -1; // 绑定失败
|
|
||||||
|
|
||||||
// 把端口设为监听
|
|
||||||
if(listen(listenfd, connections) != 0) //第二个参数+1为已连接队列(已三次握手但没有accept)
|
|
||||||
return -1;
|
|
||||||
return s_accept();
|
|
||||||
}
|
|
||||||
int TN::client(const char *ip, const char *port) {
|
|
||||||
// 创建客户端socket
|
|
||||||
iofd = socket(AF_INET, SOCK_STREAM, 0);
|
|
||||||
if(iofd == -1)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
// 向服务端请求连接
|
|
||||||
if( (h = gethostbyname(ip)) == 0) // 指定ip地址
|
|
||||||
return -1;
|
|
||||||
memset(&servaddr, 0, sizeof(servaddr));
|
|
||||||
servaddr.sin_family = AF_INET;
|
|
||||||
servaddr.sin_port = htons(atoi(port)); //指定连接端口
|
|
||||||
memcpy(&servaddr.sin_addr, h->h_addr, h->h_length);
|
|
||||||
if(connect(iofd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0) //发起连接请求
|
|
||||||
return -1; //连接失败
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int TN::s_accept() {
|
|
||||||
// 受理客户端连接请求, accept()阻塞等待
|
|
||||||
signal(SIGINT, TN_exit);signal(SIGTERM, TN_exit);
|
|
||||||
while(true) {
|
|
||||||
iofd = accept(listenfd, 0, 0);
|
|
||||||
if(iofd == -1) {
|
|
||||||
close(iofd); return -1; // 连接失败
|
|
||||||
}
|
|
||||||
int pid = fork();
|
|
||||||
if(pid == 0) { // 创建子进程处理连接
|
|
||||||
signal(SIGINT, SIG_IGN); signal(SIGTERM, SIG_DFL);
|
|
||||||
close(listenfd);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if(pid < 0) return -1;
|
|
||||||
else close(iofd);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int TN::out(char *str) {
|
|
||||||
if(send(iofd, str, strlen(str), 0) <= 0) // 发送报文
|
|
||||||
return -1; // 报文发送不成功
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int TN::in(char *str) {
|
|
||||||
//接收报文, recv()将阻塞等待
|
|
||||||
memset(str, 0, sizeof(str));
|
|
||||||
if(recv(iofd, str, sizeof(str), 0) <= 0)
|
|
||||||
return -1; // 未成功接收报文
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int TN::out(void *str, size_t fsize) {
|
|
||||||
if(send(iofd, str, fsize, 0) <= 0) // 发送报文
|
|
||||||
return -1; // 报文发送不成功
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int TN::in(void *str, size_t fsize) {
|
|
||||||
//接收报文, recv()将阻塞等待
|
|
||||||
memset(str, 0, fsize);
|
|
||||||
if(recv(iofd, str, fsize, 0) <= 0)
|
|
||||||
return -1; // 未成功接收报文
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
socklen_t TN::bufsize(size_t buf_send, size_t buf_recv) {
|
|
||||||
socklen_t optlen = sizeof(buf_send);
|
|
||||||
// 接收缓冲区大小
|
|
||||||
getsockopt(iofd, SOL_SOCKET, SO_SNDBUF, &buf_send, &optlen);
|
|
||||||
// 发送缓冲区大小
|
|
||||||
getsockopt(iofd, SOL_SOCKET, SO_RCVBUF, &buf_recv, &optlen);
|
|
||||||
return optlen;
|
|
||||||
}
|
|
||||||
|
|
||||||
int TN::nagle_off() {
|
|
||||||
int opt = 1;
|
|
||||||
setsockopt(iofd, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TN_exit(int sig) {
|
|
||||||
signal(SIGTERM, SIG_IGN); signal(SIGINT, SIG_IGN); //避免再次干扰
|
|
||||||
kill(0, SIGTERM); // 通知所有子进程退出
|
|
||||||
exit(0);
|
|
||||||
}
|
|
@ -1,64 +0,0 @@
|
|||||||
// Copyright (c) 2024 ely. All rights reserved.
|
|
||||||
// simple_TcpNet
|
|
||||||
// 宗旨:简单易用,且尽可能的自由
|
|
||||||
// versions 1.0.2
|
|
||||||
// 大版本 小版本 修订版本
|
|
||||||
#ifndef TCPNET
|
|
||||||
#define TCPNET
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <cstring>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <netdb.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <netinet/tcp.h>
|
|
||||||
|
|
||||||
class TN { // tcp socker net
|
|
||||||
private:
|
|
||||||
int iofd, listenfd;
|
|
||||||
struct hostent* h;
|
|
||||||
struct sockaddr_in servaddr;
|
|
||||||
int s_accept();
|
|
||||||
public:
|
|
||||||
TN();
|
|
||||||
~TN();
|
|
||||||
int server(const char *, int);
|
|
||||||
// 服务端的初始化函数
|
|
||||||
// 传入一个使用的端口号(请尽量用大于1024的值)和最大等待连接数
|
|
||||||
// 服务端受理并处理连接,使用多进程以连接多个客户端
|
|
||||||
// 若返回0表示成功与一个客户端建立连接
|
|
||||||
|
|
||||||
int client(const char *, const char *);
|
|
||||||
// 客户端的初始化函数
|
|
||||||
// 参数为服务端ip和端口
|
|
||||||
// 若返回0表示成功与一个服务端建立连接
|
|
||||||
|
|
||||||
// 网络I/O函数 在连接建立后即可使用此组函数进行通信
|
|
||||||
int out(char *);
|
|
||||||
int in(char *);
|
|
||||||
// 重载的任意类型IO函数,第二个参数是类型大小
|
|
||||||
int out(void *, size_t);
|
|
||||||
int in(void *, size_t);
|
|
||||||
|
|
||||||
// 查看socket发送和接收缓冲区的大小
|
|
||||||
socklen_t bufsize(size_t buf_send, size_t buf_recv);
|
|
||||||
|
|
||||||
// 禁用Nagle算法,可以减少延迟,但是带宽利用不充分
|
|
||||||
int nagle_off();
|
|
||||||
};
|
|
||||||
void TN_exit(int sig);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
HISTORY
|
|
||||||
1.0.1 调整注释和服务端端口重用问题
|
|
||||||
1.0.2 加入bufsize函数查看缓冲区大小 加入nagle_off开关
|
|
||||||
|
|
||||||
PLAN
|
|
||||||
编写高并发的封装类
|
|
||||||
*/
|
|
24
c++/universal/STL/function.md
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# function 包装器
|
||||||
|
|
||||||
|
提供更加一致的接口,避免多次实例化
|
||||||
|
|
||||||
|
对于调用特征标(call signature)一样的函数,使用function进行包装
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
std::function<double(int)> fun1;
|
||||||
|
```
|
||||||
|
+ 可接受任何函数指针,函数对象,lambda表达式
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T>
|
||||||
|
void print(T f, int a) {
|
||||||
|
std::cout << f(a) << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
double f1(int a) {
|
||||||
|
return a/1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::function<double(int)> fun1=f1;
|
||||||
|
print(fun1, 10);
|
||||||
|
```
|
@ -1,118 +1,90 @@
|
|||||||
#include <iostream>
|
# string 字符串模板
|
||||||
#include <cstring>
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
void c_char(const char *,const char *);
|
`#include <string>`
|
||||||
void c_string(const char *,const char *);
|
|
||||||
|
|
||||||
int main() {
|
## 构造
|
||||||
char a[1000],b[1000];
|
```cpp
|
||||||
cin >> a >> b; // 流读入
|
|
||||||
|
|
||||||
c_char(a, b); //c风格字符串
|
|
||||||
c_string(a, b); //string
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void c_char(const char *str1,const char *str2) {
|
|
||||||
char buf1[1000],buf2[1000];
|
|
||||||
printf("c风格字符串\n\n");
|
|
||||||
strcpy(buf1, str1); strcpy(buf2, str2);
|
|
||||||
|
|
||||||
strcpy(buf1, "hello"); // 用后面的字符串覆盖前面的字符串
|
|
||||||
strncpy(buf1, "hello", 5); // 增加指定长度
|
|
||||||
|
|
||||||
strcat(buf1, "hello"); // 连接字符串
|
|
||||||
strncat(buf1, "hello", 5);
|
|
||||||
|
|
||||||
strcmp(buf1, "hello"); // 比较字符串,相等返回0
|
|
||||||
|
|
||||||
strlen(buf1); // 返回长度,不包括'\0'
|
|
||||||
|
|
||||||
strstr(buf1, "hello"); // 返回第一次出现子串的指针
|
|
||||||
|
|
||||||
strtok(buf1, " "); // 分割字符串,返回分割过的字符串
|
|
||||||
|
|
||||||
memset(buf1, 0, sizeof(buf1));//覆写内存块
|
|
||||||
|
|
||||||
memcpy(buf1, "hello", 5); //复制内存块
|
|
||||||
|
|
||||||
memmove(buf1 + 1, buf1, 4); //移动5个字节到前一个位置
|
|
||||||
|
|
||||||
}
|
|
||||||
void c_string(const char *str1, const char *str2) {
|
|
||||||
string buf;
|
|
||||||
|
|
||||||
/*
|
|
||||||
// 构造
|
|
||||||
|
|
||||||
string(); // 默认构造,创建一个空的字符串
|
string(); // 默认构造,创建一个空的字符串
|
||||||
string(const char &str1); // c风格字符串初始化
|
string(const char &str1); // c风格字符串初始化
|
||||||
string(int n,char c); // 用字符填充一个字符串
|
string(int n,char c); // 用字符填充一个字符串
|
||||||
|
```
|
||||||
|
|
||||||
// 赋值
|
## 赋值
|
||||||
|
```cpp
|
||||||
string& operator=(const char* str1); // c风格字符串赋值给当前string类
|
string& operator=(const char* str1); // c风格字符串赋值给当前string类
|
||||||
string& operator=(const string& buf); // 另一个容器复制
|
string& operator=(const string& buf); // 另一个容器复制
|
||||||
string& operator=(const cahr c); // 字符赋值
|
string& operator=(const cahr c); // 字符赋值
|
||||||
|
```
|
||||||
|
|
||||||
// 存取
|
## 存取
|
||||||
|
```cpp
|
||||||
|
|
||||||
char& operator[](int n); // 通过[]获取字符,注意溢出
|
char& operator[](int n); // 通过[]获取字符,注意溢出
|
||||||
|
```
|
||||||
|
|
||||||
// 拼接
|
## 拼接
|
||||||
|
```cpp
|
||||||
|
|
||||||
string& operator+=(const string& str); // 追加到末尾
|
string& operator+=(const string& str); // 追加到末尾
|
||||||
string& operator+=(const char* str); // 追加到末尾
|
string& operator+=(const char* str); // 追加到末尾
|
||||||
string& operator+=(const char c); // 追加到末尾
|
string& operator+=(const char c); // 追加到末尾
|
||||||
|
```
|
||||||
|
|
||||||
// 查找
|
## 查找
|
||||||
|
```cpp
|
||||||
|
|
||||||
int find(const string& str, int pos = 0) const; // 查找str在当前字符串第一次出现的位置,pos为开始查找的位置
|
int find(const string& str, int pos = 0) const; // 查找str在当前字符串第一次出现的位置,pos为开始查找的位置
|
||||||
int find(const char* str, int pos = 0) const; // 查找str在当前字符串第一次出现的位置
|
int find(const char* str, int pos = 0) const; // 查找str在当前字符串第一次出现的位置
|
||||||
int rfind(const char* str, int pos = npos) const; // 查找str在当前字符串第一次出现的位置,反向查询
|
int rfind(const char* str, int pos = npos) const; // 查找str在当前字符串第一次出现的位置,反向查询
|
||||||
|
|
||||||
string::npos 在值上等于-1 即size_t的最大值 表示直到字符串结束
|
string::npos 在值上等于-1 即size_t的最大值 表示直到字符串结束
|
||||||
|
```
|
||||||
|
|
||||||
// 替换
|
## 替换
|
||||||
|
```cpp
|
||||||
|
|
||||||
string& replace(int pos, int n, const string& str); // 从pos开始替换,n个字符
|
string& replace(int pos, int n, const string& str); // 从pos开始替换,n个字符
|
||||||
string& replace(int pos, int n, const char* str); // 从pos开始替换,n个字符
|
string& replace(int pos, int n, const char* str); // 从pos开始替换,n个字符
|
||||||
|
```
|
||||||
|
|
||||||
// 比较
|
## 比较
|
||||||
|
```cpp
|
||||||
|
|
||||||
int compare(const string& str) const; //根据字典序
|
int compare(const string& str) const; //根据字典序
|
||||||
int compare(const char* str) const; //根据字典序
|
int compare(const char* str) const; //根据字典序
|
||||||
|
|
||||||
各种比较操作符都有重载
|
各种比较操作符都有重载
|
||||||
|
```
|
||||||
|
|
||||||
// 子串
|
## 子串
|
||||||
|
```cpp
|
||||||
string substr(int pos = 0, int n = npos) const; //返回从pos开始,长度为n的子串
|
string substr(int pos = 0, int n = npos) const; //返回从pos开始,长度为n的子串
|
||||||
|
```
|
||||||
|
|
||||||
// 插入
|
## 插入
|
||||||
|
```cpp
|
||||||
|
|
||||||
string& insert(int pos, const char* str); //在pos位置插入
|
string& insert(int pos, const char* str); //在pos位置插入
|
||||||
string& insert(int pos, const string& str); //在pos位置插入
|
string& insert(int pos, const string& str); //在pos位置插入
|
||||||
string& insert(int pos, int n, char c); //在pos位置插入
|
string& insert(int pos, int n, char c); //在pos位置插入
|
||||||
|
```
|
||||||
|
|
||||||
// 删除
|
## 删除
|
||||||
|
```cpp
|
||||||
|
|
||||||
string& erase(int pos, int n = npos); //在pos位置插入
|
string& erase(int pos, int n = npos); //在pos位置插入
|
||||||
|
```
|
||||||
|
|
||||||
# 两种转换
|
## 两种转换
|
||||||
|
```cpp
|
||||||
string str1;
|
string str1;
|
||||||
const char* str2 = str1.c_str();
|
const char* str2 = str1.c_str();
|
||||||
|
|
||||||
const char* str3;
|
const char* str3;
|
||||||
string str4(str3);
|
string str4(str3);
|
||||||
|
```
|
||||||
|
|
||||||
# 神奇转换函数
|
## 神奇转换函数
|
||||||
|
```cpp
|
||||||
string to_ strinf(任何类型); //将好多类型转换成string
|
string to_ strinf(任何类型); //将好多类型转换成string
|
||||||
|
```
|
||||||
*/
|
|
||||||
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
int main(int argv, char *argc[]) {
|
|
||||||
printf("传入了 %d 个参数\n",argv);
|
|
||||||
for(int i = 0; i < argv; i++)
|
|
||||||
printf("第%d个参数: %s\n",i+1,argc[i]);
|
|
||||||
return 0;
|
|
||||||
}
|
|
33
c++/universal/c_string.md
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
# c风格字符串
|
||||||
|
|
||||||
|
`#include <cstring>`
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
strcpy(buf1, "hello"); // 用后面的字符串覆盖前面的字符串
|
||||||
|
strncpy(buf1, "hello", 5); // 增加指定长度
|
||||||
|
|
||||||
|
strcat(buf1, "hello"); // 连接字符串
|
||||||
|
strncat(buf1, "hello", 5);
|
||||||
|
|
||||||
|
strcmp(buf1, "hello"); // 比较字符串,相等返回0
|
||||||
|
|
||||||
|
strlen(buf1); // 返回长度,不包括'\0'
|
||||||
|
|
||||||
|
strstr(buf1, "hello"); // 返回第一次出现子串的指针
|
||||||
|
|
||||||
|
strtok(buf1, " "); // 分割字符串,返回分割过的字符串
|
||||||
|
|
||||||
|
memset(buf1, 0, sizeof(buf1));//覆写内存块
|
||||||
|
|
||||||
|
memcpy(buf1, "hello", 5); //复制内存块
|
||||||
|
|
||||||
|
memmove(buf1 + 1, buf1, 4); //移动5个字节到前一个位置
|
||||||
|
```
|
||||||
|
## 两种转换
|
||||||
|
```cpp
|
||||||
|
string str1;
|
||||||
|
const char* str2 = str1.c_str();
|
||||||
|
|
||||||
|
const char* str3;
|
||||||
|
string str4(str3);
|
||||||
|
```
|
55
c++/universal/class.md
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
# 对象和类
|
||||||
|
|
||||||
|
## 访问控制
|
||||||
|
```cpp
|
||||||
|
class demo {
|
||||||
|
public: // 公有接口
|
||||||
|
private: // 私有成员
|
||||||
|
protected: // 保护
|
||||||
|
};
|
||||||
|
```
|
||||||
|
## 作用域运算符(::)
|
||||||
|
可用于在类体外指出函数所属的类(命名空间)
|
||||||
|
|
||||||
|
## 成员函数的参数名不可与类成员相同
|
||||||
|
|
||||||
|
## 类的六大特殊成员函数(未定义时编译器提供默认版本)
|
||||||
|
```cpp
|
||||||
|
demo::demo(); // 默认构造函数
|
||||||
|
demo::~demo(); // 默认析构函数
|
||||||
|
demo::demo(const demo&); // 复制构造函数
|
||||||
|
demo& demo::operator = (const demo&); // 赋值构造函数
|
||||||
|
demo::demo(demo&&); // 移动复制构造函数
|
||||||
|
demo& demo::operator = (demo&&); // 移动赋值构造函数
|
||||||
|
```
|
||||||
|
|
||||||
|
## const 成员函数 适合的成员函数要尽可能用,以帮助规避错误
|
||||||
|
`void show() const;` 声明
|
||||||
|
`void demo::show() const;` 定义
|
||||||
|
表明函数不会修改调用对象
|
||||||
|
|
||||||
|
## this指针
|
||||||
|
成员函数引用整个调用对象,可以使用 *this
|
||||||
|
|
||||||
|
## 作用域为类的常量(无法用const)
|
||||||
|
因为声明类只是描述了对象的形式,没有创建对象
|
||||||
|
+ 在类中声明一个枚举
|
||||||
|
```cpp
|
||||||
|
class const_demo {
|
||||||
|
private:
|
||||||
|
enum {Pi = 3.1415);
|
||||||
|
double s = 2*Pi;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
+ 使用关键字 static
|
||||||
|
与其他静态常量存储在一起
|
||||||
|
` class demo {static const int Months=12};`
|
||||||
|
|
||||||
|
## 作用域内枚举
|
||||||
|
`enum class egg {small, large};`
|
||||||
|
使用后需要通过枚举名限定枚举量
|
||||||
|
`egg demo1 = egg::large;`
|
||||||
|
并且关闭了隐式转换的特性
|
||||||
|
|
||||||
|
|
||||||
|
explicit 禁止单个参数构造函数导致的自动类型转换
|
@ -102,5 +102,4 @@ void stream_fio() {
|
|||||||
ios::end
|
ios::end
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
39
c++/universal/specifier_qualifier.md
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
# 存储说明符
|
||||||
|
+ static
|
||||||
|
+ extern
|
||||||
|
+ mutable
|
||||||
|
+ thread_local
|
||||||
|
|
||||||
|
# cv 说明符
|
||||||
|
+ const
|
||||||
|
+ volatile
|
||||||
|
|
||||||
|
|
||||||
|
## static
|
||||||
|
用在整个文件的声明中,表示内部连接性
|
||||||
|
局部声明中,代表存储持续性为静态
|
||||||
|
|
||||||
|
可将函数限制为内部连接性
|
||||||
|
`static void show();`
|
||||||
|
|
||||||
|
## extern
|
||||||
|
引用声明
|
||||||
|
声明引用在其他地方定义的变量
|
||||||
|
|
||||||
|
## mutable
|
||||||
|
即使结构(类)被声明为const,也可以被修改的成员函数
|
||||||
|
```cpp
|
||||||
|
struct people {
|
||||||
|
int scora;
|
||||||
|
mutable int accesses;
|
||||||
|
};
|
||||||
|
const people demo;
|
||||||
|
demo.accesses = 0;
|
||||||
|
```
|
||||||
|
|
||||||
|
## const
|
||||||
|
const 全局变量的连接性为内部(默认外部)
|
||||||
|
就像使用了static
|
||||||
|
如果希望连接性为外部,则可以用extern覆盖
|
||||||
|
|
||||||
|
## volatile 强制读内存
|
43
c++/universal/template.md
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
# 模板
|
||||||
|
|
||||||
|
## 函数模板
|
||||||
|
|
||||||
|
### 基本格式
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template <typename T>
|
||||||
|
void swap(T &a, T &b) {
|
||||||
|
T temp;
|
||||||
|
temp = b;
|
||||||
|
b = a;
|
||||||
|
a = temp;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
__函数模板必须放在头文件里,因为它不是函数实体,只能算编译指令__
|
||||||
|
|
||||||
|
### 模板的几个术语
|
||||||
|
+ **隐式实例化**
|
||||||
|
```cpp
|
||||||
|
int a=0, b=3;
|
||||||
|
swap<int>(a, b);
|
||||||
|
```
|
||||||
|
+ **显式实例化**
|
||||||
|
```cpp
|
||||||
|
template void swap<int>(int&, int&); // 使用模板生成int类型的函数定义
|
||||||
|
```
|
||||||
|
+ **显式具体化**
|
||||||
|
```cpp
|
||||||
|
template <> void swap<int>(int&, int&);
|
||||||
|
```
|
||||||
|
__这个可以放到其他文件里,因为是有实体的__
|
||||||
|
|
||||||
|
### 类型推导
|
||||||
|
+ decltype()
|
||||||
|
```cpp
|
||||||
|
int a;
|
||||||
|
decltype(a) var;
|
||||||
|
```
|
||||||
|
|
||||||
|
## 类模板
|
||||||
|
|
||||||
|
+ 同样没有实体,包括类成员方法等都要写成模板的格式
|
0
c++/windows/api/LearningPath.md
Normal file
Before Width: | Height: | Size: 414 KiB |
Before Width: | Height: | Size: 405 KiB After Width: | Height: | Size: 405 KiB |
Before Width: | Height: | Size: 397 KiB After Width: | Height: | Size: 397 KiB |
Before Width: | Height: | Size: 478 KiB After Width: | Height: | Size: 478 KiB |
@ -1,2 +0,0 @@
|
|||||||
nohup 命令挂机(退出登陆后依然执行)
|
|
||||||
nohup [command] &
|
|
@ -1,39 +0,0 @@
|
|||||||
`screen` 是一个功能强大的命令行工具,主要用于 Unix 和类 Unix 操作系统中,它允许用户开启多个独立的会话(称为"窗口"),在这些会话之间可以自由切换而不会中断已经运行的程序。以下是 `screen` 的一些主要功能和使用方法:
|
|
||||||
### 主要功能:
|
|
||||||
1. **多会话管理**:可以同时运行多个独立的 shell 会话。
|
|
||||||
2. **会话分离与重连**:可以从一个会话中分离出来,稍后再重新连接到该会话。
|
|
||||||
3. **窗口分割**:在一个 screen 会话中,可以水平或垂直分割窗口,以同时查看和操作多个任务。
|
|
||||||
4. **滚动记录**:可以查看会话的滚动记录,即使之前的输出已经滚出屏幕。
|
|
||||||
5. **复制和粘贴**:在 screen 会话中,可以使用快捷键复制文本并粘贴到其他位置。
|
|
||||||
6. **会话锁定**:可以锁定当前会话,防止他人查看或操作。
|
|
||||||
7. **自动保存会话**:在网络断开或其他异常情况下,screen 可以自动保存当前会话状态。
|
|
||||||
### 基本使用方法:
|
|
||||||
1. **启动一个新的 screen 会话**:
|
|
||||||
```bash
|
|
||||||
screen
|
|
||||||
```
|
|
||||||
2. **列出当前的 screen 会话**:
|
|
||||||
```bash
|
|
||||||
screen -ls
|
|
||||||
```
|
|
||||||
3. **重新连接到一个已存在的会话**:
|
|
||||||
```bash
|
|
||||||
screen -r [会话ID或名称]
|
|
||||||
```
|
|
||||||
4. **分离当前会话**:
|
|
||||||
在 screen 会话中按 `Ctrl-a` 然后按 `d`。
|
|
||||||
5. **在会话中创建新窗口**:
|
|
||||||
在 screen 会话中按 `Ctrl-a` 然后按 `c`。
|
|
||||||
6. **在窗口之间切换**:
|
|
||||||
在 screen 会话中按 `Ctrl-a` 然后按 `n`(下一个窗口)或 `Ctrl-a` 然后按 `p`(上一个窗口)。
|
|
||||||
7. **分割窗口**:
|
|
||||||
- 水平分割:在 screen 会话中按 `Ctrl-a` 然后按 `"`(双引号键)。
|
|
||||||
- 垂直分割:在 screen 会话中按 `Ctrl-a` 然后按 `S`。
|
|
||||||
8. **调整分割窗口的大小**:
|
|
||||||
- 增加/减少水平大小:在 screen 会话中按 `Ctrl-a` 然后按方向键。
|
|
||||||
- 增加/减少垂直大小:在 screen 会话中按 `Ctrl-a` 然后按 `Shift` 加上方向键。
|
|
||||||
9. **退出 screen 会话**:
|
|
||||||
- 关闭当前窗口:在 screen 会话中按 `Ctrl-a` 然后按 `k`。
|
|
||||||
- 退出所有窗口并结束会话:在 screen 会话中按 `Ctrl-a` 然后按 `\`。
|
|
||||||
10. **锁定当前会话**:
|
|
||||||
在 screen 会话中按 `Ctrl-a` 然后按 `x`。
|
|
@ -1,4 +0,0 @@
|
|||||||
#3 smartctl
|
|
||||||
查看硬盘状态参数
|
|
||||||
-a 全部参数
|
|
||||||
-H 是否正常
|
|
@ -1,14 +0,0 @@
|
|||||||
#5 ulimit
|
|
||||||
查看和修改进程运行资源限制
|
|
||||||
-H/S # 设置/显示 软/硬 限制
|
|
||||||
-a # 显示所有
|
|
||||||
-t # cpu time
|
|
||||||
-f # file size
|
|
||||||
-s # stack size
|
|
||||||
-c # core file size
|
|
||||||
-m # memory size
|
|
||||||
-l # lock memory size
|
|
||||||
-p # user processes
|
|
||||||
-n # open file
|
|
||||||
|
|
||||||
#ulimit -Ht 3600
|
|
@ -1,37 +0,0 @@
|
|||||||
Ubuntu 20.04.6 LTS \n \l
|
|
||||||
|
|
||||||
|
|
||||||
@@@@@@@@@@@@@@@@@ @@@ @@@@ @@ @@ @@
|
|
||||||
@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@ @@ @@ @@
|
|
||||||
@@@@ @@@ @@@ @@ @@ @@
|
|
||||||
@@@ @@@ @@ @@@@@@@@@@@@ @@ @@
|
|
||||||
@@@ @@@ @@@@@@@@@@@@@@@@@@@@@@@ @@ @@ @@ @@@@
|
|
||||||
@@@ @@ @@ @@ @@ @@ @@ @@ @@@@
|
|
||||||
@@@@ @@ @@ @@@@ @@@@ @@@ @@ @@
|
|
||||||
@@@@ @@ @@@@@@@@@@@@@@@@ @@@@ @@ @@@ @@ @@@
|
|
||||||
@@@@ @@@@ @@ @@ @@ @@@ @@ @@ @@@@ @@ @@
|
|
||||||
@@@ @@@@@ @@ @@ @@ @@@@ @@ @@ @@ @@
|
|
||||||
@@@ @@@@@@@@@@@@@@@@ @@ @@ @@ @@@
|
|
||||||
@@@ @@ @@ @@ @@ @@ @@ @@@
|
|
||||||
@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@ @ @@ @@ @@@ @@@@@
|
|
||||||
@@@ @@ @@@ @@ @@@ @@@@@@@@
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ @@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@ aa
|
|
||||||
@@@ @@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@ @@@
|
|
||||||
@@ @@ @@@ @@@
|
|
||||||
@ @@@@@@@@@@@@@@@@@ @@ @@ @@ @@@ @@@
|
|
||||||
@@@@@@@@@@@@@@@@ @@@@ @@ @@ @@ @@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@
|
|
||||||
@@@ @@@ @@@@@@@@@ @@ @@@@@@@@@@@@@@@@@@@@@ @@@@ @@ @@@
|
|
||||||
@@ @@@@@@@@@@@ @@@ @@ @@ @@ @@@ @@@ @@ @@@ @@@ @@ @@@
|
|
||||||
@@ @@ @@ @@@ @@ @@ @@ @@@ @@ @@ @@@ @@@ @@@
|
|
||||||
@@ @@ @@ @@@ @@ @@ @@ @@ @@ @@ @@ @@ @@@ @@@@@@@@@@@@@@@@
|
|
||||||
@@ @@@@@@@@ @@ @@@ @@@@ @@ @ @@ @@ @@ @@@ @@@
|
|
||||||
@@ @@ @@@ @@ @@ @@ @@ @@ @@@ @@@
|
|
||||||
@@ @@@ @@ @@ @ @@ @@ @@ @@@ @@@
|
|
||||||
@@ @@ @@@ @@@ @@@ @@ @@ @@ @@@ @@@ @v
|
|
||||||
@@@@ @@@ @@@@@@@@@@@@ @@@@ @@@@@@@@@@@@@@@@@@@@@@@@@o
|
|
143
python/basics/demo.py
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
a1 = int(input("input:")) # input
|
||||||
|
print('%8d'%a1, '\n') # print
|
||||||
|
# print(objects, sep=' ', wnd='\n')
|
||||||
|
|
||||||
|
|
||||||
|
# 数据类型
|
||||||
|
x1 = 123
|
||||||
|
x2 = 123.123
|
||||||
|
x3 = True
|
||||||
|
x4 = "True"
|
||||||
|
|
||||||
|
print(x1, " ", type(x1))
|
||||||
|
print(x2, " ", type(x2))
|
||||||
|
print(x3, " ", type(x3))
|
||||||
|
print(x4, " ", type(x4))
|
||||||
|
print()
|
||||||
|
|
||||||
|
|
||||||
|
# 运算符
|
||||||
|
"""
|
||||||
|
1. **
|
||||||
|
2. * / % //
|
||||||
|
3. + -
|
||||||
|
4. <= < > >=
|
||||||
|
5. <> == !=
|
||||||
|
6. = %= /= //= -= += *= **=
|
||||||
|
7. not or and
|
||||||
|
"""
|
||||||
|
|
||||||
|
# 条件判断
|
||||||
|
if (x1==a1) and (x3==True):
|
||||||
|
print("OK!!!")
|
||||||
|
elif x3==False:
|
||||||
|
print("x3==False")
|
||||||
|
else:
|
||||||
|
print("x1:", x1)
|
||||||
|
print("a1:", a1)
|
||||||
|
print()
|
||||||
|
|
||||||
|
|
||||||
|
# 循环控制
|
||||||
|
for i in range(10): # 逐一访问序列中的元素
|
||||||
|
while i>=9 and i<13: # 通过条件控制
|
||||||
|
print(i)
|
||||||
|
i+=1
|
||||||
|
continue
|
||||||
|
break
|
||||||
|
|
||||||
|
# range() 函数 创建一个整数列表
|
||||||
|
"""
|
||||||
|
# 基本格式
|
||||||
|
range(start, stop,[step])
|
||||||
|
# 开始 结束 步长
|
||||||
|
range(5, 1, -1) # 可做到倒序输出
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
# 字符串
|
||||||
|
s = str("Hello world")
|
||||||
|
|
||||||
|
print(s[3])
|
||||||
|
print(s[-3])
|
||||||
|
print(s[0:3]) # 字符串切片
|
||||||
|
print(s[3:])
|
||||||
|
print(s[:5])
|
||||||
|
print(s[:-5])
|
||||||
|
print(s[::-1]) # 倒序
|
||||||
|
len(s) # 计算长度
|
||||||
|
|
||||||
|
# 字符串查询
|
||||||
|
s.find('w')
|
||||||
|
s.count('l')
|
||||||
|
|
||||||
|
s.replace('H','h') # H变成h
|
||||||
|
s.casefold() # 大写转小写
|
||||||
|
s.upper() # 小写转大写
|
||||||
|
s.swapcase() # 转换大小写
|
||||||
|
eval('12+3') # 计算值 返回15
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 列表
|
||||||
|
li1 = [] # 创建空列表
|
||||||
|
li2 = list()
|
||||||
|
li3 = list(s) # 转换字符串成列表
|
||||||
|
li3.index('H') # 返回对应值的下标 反查
|
||||||
|
li4 = s.split(' ') # 通过空格分割字符串成列表
|
||||||
|
# li1[start:end:step]
|
||||||
|
|
||||||
|
for i,t in enumerate(li3): # 同时输出索引和值(列表本身也可以直接作为循环的序列)
|
||||||
|
print(i,t)
|
||||||
|
|
||||||
|
# 列表的更新与排序
|
||||||
|
li1.append([26,71]) # [26,71]作为一个元素追加到末尾
|
||||||
|
li1.extend([26,71]) # 将[26,71]每一项合并到末尾
|
||||||
|
li1.insert(1,520) # 将520插入位置1
|
||||||
|
li1[0] = 1314 # so easy
|
||||||
|
li1.remove(3) # 删除指定位置元素
|
||||||
|
li1.pop() # 默认删除-1位置的元素
|
||||||
|
li1.sort() # 对列表本身排序
|
||||||
|
li1.sort(reverse=True) # 对列表本身排序(倒序)
|
||||||
|
li2 = sorted.(li1) # 返回一个排序完的列表
|
||||||
|
|
||||||
|
|
||||||
|
# 元组tuple 元素不可修改的列表
|
||||||
|
t1 = ()
|
||||||
|
t1 = tuple(li1)
|
||||||
|
|
||||||
|
|
||||||
|
# 集合 set
|
||||||
|
set1 = {4,3,2,1}
|
||||||
|
set2 = set(li1)
|
||||||
|
set3 = set1 & set2 # 交集
|
||||||
|
set3 = set1 | set2 # 并集
|
||||||
|
set3 = set1 - set2 # 差集
|
||||||
|
set3.add(123) # 添加
|
||||||
|
set3.remove(123) # 删除
|
||||||
|
sum(set3) # 求总个数
|
||||||
|
|
||||||
|
|
||||||
|
# 字典 dict
|
||||||
|
dict1 = {'你好':'Hello'}
|
||||||
|
dict2 = zip(li1,li2) # 通过两个列表创建字典
|
||||||
|
del dict1['你好'] # 删除元素
|
||||||
|
dict1['再见'] = 'bey' # 存在更新,不存在添加
|
||||||
|
dict1.setdefault('好','OK') # 存在不修改,不存在添加
|
||||||
|
|
||||||
|
s = dict1.get('好','NO') # 不存在追加,存在返回原值不修改
|
||||||
|
|
||||||
|
for i,t in dict1.items(): # 遍历所有键值对
|
||||||
|
print(i,t)
|
||||||
|
for i in dict1.keys(): # 遍历所有键
|
||||||
|
print(i)
|
||||||
|
for i in dict1.values(): # 遍历所有值
|
||||||
|
print(i)
|
||||||
|
|
||||||
|
|
||||||
|
# 函数
|
||||||
|
def jc(n):
|
||||||
|
ans = 1;
|
||||||
|
for i in range(n):
|
||||||
|
ans *= i
|
||||||
|
return ans
|
9
python/modular/math.py
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
from math import *
|
||||||
|
|
||||||
|
n=(int)input()
|
||||||
|
ceil(n/24) # 上取整
|
||||||
|
round() # 四舍五入
|
||||||
|
abs() # 绝对值
|
||||||
|
max() # 最大值
|
||||||
|
min() # 最小值
|
||||||
|
pow(2,2) # 乘方
|
10
python/modular/random.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
from random import *
|
||||||
|
random() [0,1) # float
|
||||||
|
unifom(2.6, 7.1) [2.6,7.1] # float
|
||||||
|
|
||||||
|
randint(1, 10) [1,10] # int
|
||||||
|
randrange(1, 10) [1,10) # int
|
||||||
|
randrange(1, 10, 2) [1,10) # int %2==1
|
||||||
|
|
||||||
|
choice(list) # from list rand
|
||||||
|
choice(list, 2) # from list two
|
@ -14,9 +14,13 @@ git init #创建仓库
|
|||||||
--bare <code.git> #没有工作树的选项(多用于git服务器)
|
--bare <code.git> #没有工作树的选项(多用于git服务器)
|
||||||
|
|
||||||
git add 文件 #将文件放到暂存区
|
git add 文件 #将文件放到暂存区
|
||||||
* #所有 新建的,删除的,修改的
|
-n 演习
|
||||||
. #新建的,修改的
|
* 所有 新建的,删除的,修改的
|
||||||
-u #删除的,修改的
|
. 新建的,修改的
|
||||||
|
-u 更新已追踪
|
||||||
|
-f 允许添加忽略的文件
|
||||||
|
-A, --all 添加所有已跟踪和未跟踪
|
||||||
|
|
||||||
|
|
||||||
git commit #将暂存区修改合成一个提交
|
git commit #将暂存区修改合成一个提交
|
||||||
-m "填写概要"
|
-m "填写概要"
|
||||||
@ -39,12 +43,16 @@ git diff #比对差异 与暂存区差异
|
|||||||
|
|
||||||
git reflog #查询历史操作
|
git reflog #查询历史操作
|
||||||
|
|
||||||
git branch #显示所有分支
|
git branch #显示本地分支
|
||||||
xxx #创建名为 xxx 的分支
|
xxx #创建名为 xxx 的分支
|
||||||
-a #查看当前工作分支相关信息
|
-a #查看全部分支
|
||||||
-r #列出远端仓库的所有分支
|
-r #列出远端分支
|
||||||
-d/D #删除分支 大写强制
|
-d/D #删除分支 大写强制
|
||||||
-m/M #修改主分支 大写强制
|
-m/M #修改主分支 大写强制
|
||||||
|
-u <remote>/<branch> #设置追踪关系
|
||||||
|
-vv #查看每个分支的最后提交信息和跟踪关系
|
||||||
|
--merged #列出所有已合并到当前分支的分支
|
||||||
|
--no-merged #未合并
|
||||||
|
|
||||||
git checkout #切换分支
|
git checkout #切换分支
|
||||||
xxx #切换到 xxx 分支
|
xxx #切换到 xxx 分支
|
||||||
@ -52,10 +60,20 @@ git checkout #切换分支
|
|||||||
[file] #未提交的文件撤销修改
|
[file] #未提交的文件撤销修改
|
||||||
[hash] #回退
|
[hash] #回退
|
||||||
|
|
||||||
|
git switch #切换分支
|
||||||
|
-c xxx #创建并切换到 xxx 分支
|
||||||
|
|
||||||
git merge #合并分支
|
git merge #合并分支
|
||||||
xxx #将 xxx 分支合并到当前工作分支
|
xxx #将 xxx 分支合并到当前工作分支
|
||||||
--no-ff #在历史记录中记录合并
|
--no-ff #在历史记录中记录合并 (尽量加这个)
|
||||||
--squash #将分支合并为一个提交进行合并,简化历史
|
--squash #将分支合并为一个提交进行合并,简化历史
|
||||||
|
--abort #假如合并过程中出现冲突,可使用这个命令终止合并
|
||||||
|
-m <message> #提交信息
|
||||||
|
--edit #创建合并提交前,允许编辑提交信息
|
||||||
|
#
|
||||||
|
# 若产生冲突,解决冲突后,需进行以下操作
|
||||||
|
# git add
|
||||||
|
# git commit
|
||||||
|
|
||||||
git reset #回溯
|
git reset #回溯
|
||||||
--hard HEAD~1 #撤销最后一次commit 本地仓库 and 暂存区 and 工作树
|
--hard HEAD~1 #撤销最后一次commit 本地仓库 and 暂存区 and 工作树
|
||||||
@ -66,9 +84,11 @@ git revert #提交一个反commit用于撤销前面的commit
|
|||||||
HEAD
|
HEAD
|
||||||
[hash]
|
[hash]
|
||||||
|
|
||||||
git rebase #变基
|
git rebase #变基 将一系列提交从一个分支上移植到另一个分支上
|
||||||
-i #压缩历史
|
<basebranch> #将当前分支更改应用到<basebranch>分支上
|
||||||
xxx #尝试与xxx分支同步合并
|
-i #压缩历史 交互式变基
|
||||||
|
# -i HEAD~N #回退N次提交
|
||||||
|
--onto <newbase> <branch> #将<branch>分支变基到<newbase>上
|
||||||
--abort #当冲突时撤销合并
|
--abort #当冲突时撤销合并
|
||||||
--continue #继续合并
|
--continue #继续合并
|
||||||
|
|
||||||
@ -79,7 +99,7 @@ git stash #保存工作区当前状态
|
|||||||
list #查看存储状态
|
list #查看存储状态
|
||||||
pop #将最新一次记录恢复并删除
|
pop #将最新一次记录恢复并删除
|
||||||
apply #默认恢复最新记录
|
apply #默认恢复最新记录
|
||||||
clear #清楚所有记录
|
clear #清除所有记录
|
||||||
show #看当前与栈顶差异
|
show #看当前与栈顶差异
|
||||||
save xxx #提交注释
|
save xxx #提交注释
|
||||||
|
|
||||||
@ -103,9 +123,13 @@ git push #推送到远程
|
|||||||
|
|
||||||
git pull #拉取远端仓库 全部 = git fetch + git merge
|
git pull #拉取远端仓库 全部 = git fetch + git merge
|
||||||
origin xxx #直接覆盖当前工作树
|
origin xxx #直接覆盖当前工作树
|
||||||
--rebase # = git fetch + git rebase HEAD
|
--rebase #将本地分支的提交应用到拉取的提交之上,保持历史线性
|
||||||
|
--no-commit #拉取并合并代码,但不自动提交结果
|
||||||
|
--edit #创建合并提交前,允许编辑提交信息
|
||||||
|
|
||||||
git fetch #拉取到本地仓库中 不对工作树进行覆盖
|
git fetch #拉取到本地仓库中 不对工作树进行覆盖
|
||||||
|
--all #获取所有远端仓库更新
|
||||||
|
--prune #拉取更新时,清理已删除的分支
|
||||||
|
|
||||||
git tag #查看所有标签
|
git tag #查看所有标签
|
||||||
-d #删除标签
|
-d #删除标签
|
67
tool/makedown.md
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
大标题
|
||||||
|
======
|
||||||
|
|
||||||
|
中标题
|
||||||
|
------
|
||||||
|
|
||||||
|
# 一级标题
|
||||||
|
###### 六级标题
|
||||||
|
|
||||||
|
|
||||||
|
## 换行
|
||||||
|
+ 行末</br>
|
||||||
|
+ 两个空行
|
||||||
|
+ 行末两个空格
|
||||||
|
|
||||||
|
|
||||||
|
## 强调
|
||||||
|
+ *斜体*
|
||||||
|
+ **粗体**
|
||||||
|
+ ***粗斜体***
|
||||||
|
|
||||||
|
|
||||||
|
## 代码行
|
||||||
|
```cpp
|
||||||
|
#include<iostream>
|
||||||
|
int main() {
|
||||||
|
std::cout << "Hello makedown \n";
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## 表格
|
||||||
|
|
||||||
|
|---|表头|表头|
|
||||||
|
|---|----|----|
|
||||||
|
| x | XX | XX |
|
||||||
|
| x | XX | XX |
|
||||||
|
|
||||||
|
+ -: 右对齐
|
||||||
|
+ :- 左对齐
|
||||||
|
+ :-: 居中
|
||||||
|
|
||||||
|
|
||||||
|
## 图片
|
||||||
|
+ 
|
||||||
|
|
||||||
|
|
||||||
|
## 链接
|
||||||
|
+ [链接名](链接地址)
|
||||||
|
|
||||||
|
|
||||||
|
## 其他
|
||||||
|
+ ~~删除线~~
|
||||||
|
+ <u>下划线</u>
|
||||||
|
+ [^READ]:脚注
|
||||||
|
|
||||||
|
|
||||||
|
## 列表
|
||||||
|
* 项目
|
||||||
|
+ 项目
|
||||||
|
- 项目
|
||||||
|
|
||||||
|
|
||||||
|
## 区块
|
||||||
|
>
|
||||||
|
> >
|
||||||
|
> > >
|
20
tool/nmap
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# 一般探测步骤
|
||||||
|
# 1.主机发现
|
||||||
|
# 2.端口扫描
|
||||||
|
|
||||||
|
|
||||||
|
nmap -p- [目标] # 扫描全部TCP端口
|
||||||
|
nmap -p [端口] # 扫描指定TCP端口
|
||||||
|
|
||||||
|
nmap -sT # 使用TCP扫描 , 完成握手流程
|
||||||
|
nmap -sU # 使用UDP扫描
|
||||||
|
nmap -sS # 不完成整个握手过程
|
||||||
|
nmap -sUV # UDP + 版本探测 确认目标主机状态
|
||||||
|
nmap -sUV --top-ports 100 # 扫描常用的100端口
|
||||||
|
|
||||||
|
# UDP 由于探测不稳定性高,采用多次探测,因此速度慢
|
||||||
|
|
||||||
|
nmap -sn [目标] # ping 可用'-' 进行范围探测,内网ARP,外网ICMP包(会被windows server拦截)
|
||||||
|
nmap -sn 192.168.0.1-100
|
||||||
|
nmap -Pn [目标] # 可以绕过防火墙(慢) 不用Ping
|
||||||
|
|
@ -4,6 +4,8 @@ g++ -o test test.o #链接
|
|||||||
|
|
||||||
g++ -O1/-O2/-O3 // 优化选项
|
g++ -O1/-O2/-O3 // 优化选项
|
||||||
|
|
||||||
|
g++ -S -o - -fverbose-asm xxx.cpp > xxx.s // 输出带注释的汇编
|
||||||
|
|
||||||
|
|
||||||
#静态库制作:
|
#静态库制作:
|
||||||
g++ -c -o libtest.a {test.cpp 源代码文件清单}
|
g++ -c -o libtest.a {test.cpp 源代码文件清单}
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
INCLUDE = -I/home/e0x2d/include
|
|
||||||
main: file1.o file2.o
|
|
||||||
g++ -o $@ file1.o file2.o
|
|
||||||
|
|
||||||
file1.o: file1.cpp
|
|
||||||
g++ -c file1.o file1.cpp
|
|
||||||
|
|
||||||
file2.o: file2.cpp
|
|
||||||
g++ -c file2.o file2.cpp ${INCLUDE}
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm *.o demo
|
|
46
tool/program/makefile.md
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
# makefile
|
||||||
|
|
||||||
|
makefile 是一个通用的项目代码构建器
|
||||||
|
由规则 依赖 命令构成
|
||||||
|
|
||||||
|
规则:依赖
|
||||||
|
命令
|
||||||
|
|
||||||
|
+ -n 参数可以打印出make会执行的命令,但不真正执行
|
||||||
|
|
||||||
|
# 注意: 命令前面必须要用Tab
|
||||||
|
|
||||||
|
# 伪目标
|
||||||
|
.PHONY:clean
|
||||||
|
|
||||||
|
# 自动变量
|
||||||
|
$@ 目标文件
|
||||||
|
$< 第一个依赖文件
|
||||||
|
$^ 全部的依赖文件
|
||||||
|
|
||||||
|
# 普通变量定义
|
||||||
|
OPTION = -O3 -Wall
|
||||||
|
|
||||||
|
# 变量使用
|
||||||
|
g++ $(OPTION) xxx
|
||||||
|
|
||||||
|
# 使用通配符
|
||||||
|
%.o: %.c
|
||||||
|
g++ $(OPTION) -c $< -o $@
|
||||||
|
|
||||||
|
|
||||||
|
```makefile
|
||||||
|
.PHONY:clean
|
||||||
|
INCLUDE = -I/home/e0x2d/include
|
||||||
|
main: file1.o file2.o
|
||||||
|
g++ -o $@ file1.o file2.o
|
||||||
|
|
||||||
|
file1.o: file1.cpp
|
||||||
|
g++ -c file1.o file1.cpp
|
||||||
|
|
||||||
|
file2.o: file2.cpp
|
||||||
|
g++ -c file2.o file2.cpp ${INCLUDE}
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm *.o demo
|
||||||
|
```
|
11
tool/program/objdump.txt
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
objdump
|
||||||
|
-f 显示文件头
|
||||||
|
-h 显示段(section)信息
|
||||||
|
-d 反汇编可执行段
|
||||||
|
-D 反汇编所有
|
||||||
|
-t 显示符号表
|
||||||
|
-T 动态符号表
|
||||||
|
-r 重定位
|
||||||
|
-R 动态重定位
|
||||||
|
-S 源码和汇编混合
|
||||||
|
-i 显示可用的架构,和目标结构
|
44
tool/program/readelf.md
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
# 在 Linux 系统中用于显示 ELF 格式文件信息的命令行工具
|
||||||
|
|
||||||
|
+ -a, --all
|
||||||
|
显示所有可用的信息。
|
||||||
|
+ -h, --file-header
|
||||||
|
显示 ELF 文件头信息。
|
||||||
|
+ -l, --program-headers
|
||||||
|
显示程序头表。
|
||||||
|
+ -S, --section-headers
|
||||||
|
显示节头表。
|
||||||
|
+ -g, --section-groups
|
||||||
|
显示节组。
|
||||||
|
+ -t, --section-details
|
||||||
|
显示节的详细信息。
|
||||||
|
+ -e, --headers
|
||||||
|
等同于 -h -l -S。
|
||||||
|
+ -s, --syms
|
||||||
|
显示符号表。
|
||||||
|
+ --dyn-syms
|
||||||
|
显示动态符号表。
|
||||||
|
+ -N, --dynamic
|
||||||
|
显示动态段。
|
||||||
|
+ -u, --unwind
|
||||||
|
显示 unwind 信息。
|
||||||
|
+ -I, --histogram
|
||||||
|
显示桶的直方图。
|
||||||
|
+ -x, --hex-dump=<section>
|
||||||
|
以十六进制形式转储指定节的内容。
|
||||||
|
+ -d, --use-dynamic
|
||||||
|
使用动态符号表代替静态符号表。
|
||||||
|
+ -r, --relocs
|
||||||
|
显示重定位入口。
|
||||||
|
+ -i, --notes
|
||||||
|
显示.note 节。
|
||||||
|
+ -A, --arch-specific
|
||||||
|
显示架构特定的信息。
|
||||||
|
+ -D, --dynamic-symbols
|
||||||
|
显示动态符号表。
|
||||||
|
+ -W, --wide
|
||||||
|
允许输出超过 80 个字符宽。
|
||||||
|
+ -H, --help
|
||||||
|
显示帮助信息。
|
||||||
|
+ -V, --version
|
||||||
|
显示版本信息。
|
5
tool/program/regexr.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# 正则表达式
|
||||||
|
|
||||||
|
## 学习工具
|
||||||
|
+ https://regexr.com 查询网站
|
||||||
|
+ regex-vis.com 可视化表达式
|
@ -1,36 +1,42 @@
|
|||||||
SSH免密登录是一种使用SSH协议进行身份验证的方法,它允许用户在不输入密码的情况下登录远程服务器。以下是实现SSH免密登录的基本步骤:
|
# ssh 隧道转发
|
||||||
|
> 本地转发
|
||||||
|
+ 本地端口转发到远端服务器
|
||||||
|
+ ssh -L local_port:remote_host:remote_port user@ssh_server
|
||||||
|
|
||||||
|
> 远程转发
|
||||||
|
+ 远程转发到本地
|
||||||
|
+ ssh -R remote_host:local_host:local_port user@ssh_server
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
SSH免密登录是一种使用SSH协议进行身份验证的方法,它允许用户在不输入密码的情况下登录远程服务器。以下是实现SSH免密登录的基本步骤:
|
||||||
1. **生成密钥对**:
|
1. **生成密钥对**:
|
||||||
- 在本地机器上打开终端或命令提示符。
|
|
||||||
- 使用`ssh-keygen`命令生成一对公钥和私钥。例如:
|
- 使用`ssh-keygen`命令生成一对公钥和私钥。例如:
|
||||||
```bash
|
|
||||||
ssh-keygen -t rsa -b 4096
|
ssh-keygen -t rsa -b 4096
|
||||||
```
|
|
||||||
2. **复制公钥到远程服务器**:
|
2. **复制公钥到远程服务器**:
|
||||||
- 使用`ssh-copy-id`命令将公钥复制到远程服务器。例如:
|
- 使用`ssh-copy-id`命令将公钥复制到远程服务器。例如:
|
||||||
```bash
|
|
||||||
ssh-copy-id user@remote_host
|
ssh-copy-id user@remote_host
|
||||||
```
|
|
||||||
- 这将自动将你的公钥添加到远程服务器的`~/.ssh/authorized_keys`文件中。
|
- 这将自动将你的公钥添加到远程服务器的`~/.ssh/authorized_keys`文件中。
|
||||||
|
|
||||||
3. **配置SSH客户端**:
|
3. **配置SSH客户端**:
|
||||||
- 确保你的SSH客户端配置文件`~/.ssh/config`正确设置,以便使用私钥进行身份验证。例如:
|
- 确保你的SSH客户端配置文件`~/.ssh/config`正确设置,以便使用私钥进行身份验证。例如:
|
||||||
4. **禁用密码登录**:
|
4. **禁用密码登录**:
|
||||||
- /etc/ssh/sshd_config
|
- /etc/ssh/sshd_config
|
||||||
- 设置PasswordAuthentication no
|
- 设置PasswordAuthentication no
|
||||||
5. **测试免密登录**:
|
5. **测试免密登录**:
|
||||||
- 尝试使用SSH连接到远程服务器,如果一切设置正确,你将能够无需输入密码直接登录。
|
|
||||||
|
|
||||||
6. **注意事项**:
|
6. **注意事项**:
|
||||||
- 确保远程服务器的SSH服务配置允许密钥认证。通常在`/etc/ssh/sshd_config`文件中设置。
|
- 确保远程服务器的SSH服务配置允许密钥认证。通常在`/etc/ssh/sshd_config`文件中设置。
|
||||||
- 确保本地和远程的SSH配置文件没有错误,并且权限设置正确。
|
- 确保本地和远程的SSH配置文件没有错误,并且权限设置正确。
|
||||||
|
|
||||||
7. **安全性**:
|
以上步骤应该可以帮助你设置SSH免密登录。如果你遇到任何问题,可以查看SSH的日志文件或使用`-v`参数进行调试,例如:
|
||||||
- 使用强密码短语保护你的私钥文件。
|
|
||||||
- 定期更换密钥对以提高安全性。
|
|
||||||
|
|
||||||
以上步骤应该可以帮助你设置SSH免密登录。如果你遇到任何问题,可以查看SSH的日志文件或使用`-v`参数进行调试,例如:
|
|
||||||
```bash
|
|
||||||
ssh -v user@remote_host
|
ssh -v user@remote_host
|
||||||
```
|
|
||||||
这将提供详细的调试信息,帮助你诊断问题。
|
# ssh: config 文件
|
||||||
|
Host iaalai
|
||||||
|
HostName api.iaalai.cn #连接地址
|
||||||
|
User e0x1a #连接用户名
|
||||||
|
Port 20022 #连接端口
|
||||||
|
IdentityFile ~/.ssh/id_rsa #密钥地址
|
||||||
|
IdentitiesOnly yes #仅使用密钥
|
||||||
|
ServerAliveInterval 60 #每60s发一个空包保持连接
|
||||||
|
ServerAliveCountMax 3 #3次未响应断开
|
@ -37,9 +37,3 @@ augroup numbertoggle 智能切换绝对行号和相对行号
|
|||||||
autocmd BufEnter,FocusGained,InsertLeave,WinEnter * if &nu && mode() != "i" | set rnu | endif
|
autocmd BufEnter,FocusGained,InsertLeave,WinEnter * if &nu && mode() != "i" | set rnu | endif
|
||||||
autocmd BufLeave,FocusLost,InsertEnter,WinLeave * if &nu | set nornu | endif
|
autocmd BufLeave,FocusLost,InsertEnter,WinLeave * if &nu | set nornu | endif
|
||||||
augroup END
|
augroup END
|
||||||
|
|
||||||
" vim笔记
|
|
||||||
" 使用 q[Key] 开始录制宏,再次点击q结束录制
|
|
||||||
" @[Key] 调用宏
|
|
||||||
"
|
|
||||||
" # 键向上查找当前单词
|
|
9
tool/vim/ShortcutKeys.md
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# 小技巧
|
||||||
|
使用 q[Key] 开始录制宏,再次点击q结束录制
|
||||||
|
@[Key] 调用宏
|
||||||
|
|
||||||
|
# 快捷键
|
||||||
|
|
||||||
|
## ]f
|
||||||
|
在文件中若出现文件名,指针放在上面使用这个快捷键可直接打开
|
||||||
|
|
5
tool/web/game
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
indienova.com # 冰与火之舞
|
||||||
|
zh.minecraft.wiki
|
||||||
|
https://slowroads.io/
|
||||||
|
https://www.geo-fs.com/
|
||||||
|
yorg.io
|
17
tool/web/live
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
中国裁判文书网(https://wenshu.court.gov.cn/)
|
||||||
|
国家企业信用信息公示系统(https://gs.gsxt.gov.cn/index.html)
|
||||||
|
国家社会保险服务平台(https://si.12333.gov.cn/)
|
||||||
|
天地图(https://www.tianditu.gov.cn/)
|
||||||
|
国家统计局(https://www.stats.gov.cn/)
|
||||||
|
中国商标网(https://sbj.cnipa.gov.cn/sbj/index.html)
|
||||||
|
国家法律法规数据库(https://flk.npc.gov.cn/)
|
||||||
|
中国专利公布公告网(http://epub.cnipa.gov.cn/)
|
||||||
|
国家标准全文公开系统(https://openstd.samr.gov.cn/bzgk/gb/)
|
||||||
|
国家药品监督管理局(https://www.nmpa.gov.cn/datasearch/home-index.html#category=yp)
|
||||||
|
食品安全抽检公布结果查询系统(https://spcjsac.gsxt.gov.cn/)
|
||||||
|
发票查验平台(https://inv-veri.chinatax.gov.cn/?p=51,42&a=cjfb)
|
||||||
|
工信部申诉受理中心(https://ythzxfw.miit.gov.cn/index)
|
||||||
|
合同示范文本库(https://htsfwb.samr.gov.cn/)
|
||||||
|
中国法律服务网(https://www.12348.gov.cn/#/homepage)
|
||||||
|
中国庭审公开网(https://tingshen.court.gov.cn/)
|
||||||
|
中国关键词(http://keywords.china.org.cn/index.htm)
|
4
tool/web/program
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
https://mirrors.tuna.tsinghua.edu.cn/ # 清华开源站
|
||||||
|
https://linux.vbird.org/ # 鸟哥linux
|
||||||
|
https://www.52hb.com/ # 吾爱
|
||||||
|
|
6
tool/web/study
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
国家智慧教育公共服务平台(https://gjzwfw.www.gov.cn/)
|
||||||
|
终身教育平台(https://le.ouchn.cn/home)
|
||||||
|
国家数字图书馆(https://www.nlc.cn/web/index.shtml)
|
||||||
|
国家哲学社会科学文献(https://www.ncpssd.org/)
|
||||||
|
国家高等教育智慧教育平台(https://www.chinaooc.com.cn/)
|
||||||
|
职业教育专业教学资源库(https://zyk.icve.com.cn/)
|
5
tool/web/tool
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
kimi.moonshot.cn # kimi
|
||||||
|
www.tbtool.cn # 图吧
|
||||||
|
https://www.intel.cn/content/www/cn/zh/ark.html # intel CPU参数查询
|
||||||
|
https://cn.aliyun.com/ # 阿里云
|
||||||
|
https://next.itellyou.cn/ # 镜像站
|