Android .rc规则详解与init 启动

news2024/11/13 16:02:58

系列文章请扫关注公众号!

简介

Android的init进程是启动各种服务的核心进程,并处理属性设置等。怎么启动各个服务和监听属性的呢?启动过程中会解析rc文件,并存下来。当系统属性更改或启动某项服务时,init就会按照rc中的设置运行对应应用。

Init 语言:http://aospxref.com/android-10.0.0_r47/xref/system/core/init/README.md

Rc文件是按照一定规范组成的。分为5大类语句:Actions, Commands, Services, Options,Imports.

C++/java都是面向对象的语言,init语言是面向行的,就是一行就是一个语句。由空格分隔。也可使用\插入空格,双引号可防止空格拆分文本,即双引号下是一个整体。行最后使用\表示折行,即续接下行。

#开头的是注释

引用系统属性使用${property.name},还可以字符拼接;例如 `import /init.recovery.${ro.hardware}.rc`

Actions  Services 开头等于隐式声明了一个section,所有的CommandsOptions都属于这个section。

Services只有唯一的名字,如果名字重复,第二个将被忽略,并输出异常log。

Init rc文件

是以rc为后缀的文本文件

/init.rc是重要文件,在init进程启动时加载,并负责初始化系统设置。在加载完/init.rc后,执行first stage mount即加载/{system,vendor,odm}/etc/init/路径的rc文件,实现/system, /vendor

的挂载。

Mount_all命令可以指定fstab文件,挂载相应分区。没有指定就搜索默认路径/{system,vendor,odm}/etc/init/。这主要是为了支持工厂模式和其它非标准启动模式。正常启动应该使用如下3个路径的。

  1. /system/etc/init/ 用于系统核心项,例如SurfaceFlinger, MediaService,logcatd.

  2. /vendor/etc/init/ 用于SoC vendor 项,例如core SoC 需要的actions daemons.

  3. /odm/etc/init/ 给设备制造商使用, 例如外设、运动传感器等。

/{system,vendor,odm}目录下的bin文件都在其对应的 /etc/init/下有其对应项。系统中存在一个编译宏LOCAL_INIT_RC给开发者使用。每一个rc文件应该包含某个服务的全部关联操作。

例如:logcat

system/core/logcat/Android.bp

system/core/logcat/logcatd.rc

Init 加载logcatd.rc并将任务放入队列,合适时机运行。

根据init .rc文件的守护进程拆分init .rc文件比以前使用的整体init .rc文件更好。这样可以确保init读取的是唯一的服务entry和action,还有助于解决服务冲突。

mount_all命令可以有"early" "late"两个选项。当在可选路径后带 "early"init可执行程序将跳过挂载分区中带有"latemount" flag的挂载项,并触发fs 加密状态事件。设置"late" 选项后,不导入rc文件并只挂载带"latemount" flag的项。如果没有设置就会mount所有项。

Actions 理解为一系列命令操作,并有一个触发器 trigger。trigger决定Action何时执行。当有一个事件匹配了Action的trigger,就会将此Action放入to_be_excuted queue的尾部。如果已经在to_be_excuted queue中就跳过。

Action按顺序执行,Action中的command也按顺序执行。

Init在两个命令中间可以执行服务重启等任务:(device creation/destruction, property setting, process restarting)

Actions 格式:

 

     on <trigger> [&& <trigger>]*

        <command>

        <command>

        <command>

Action的执行顺序按照添加队列的顺序执行,也就是import导入的顺序放入队列,然后按照单个文件顺序执行。

例如一个文件包含

 on boot

        setprop a 1

        setprop b 2

 

     on boot && property:prop_true=true

        setprop c 1

        setprop d 2

 

     on boot

        setprop e 1

        setprop f 2

当trigger boot时并且 属性prop_true的值是true,顺序执行的结果是:

     setprop a 1

     setprop b 2

     setprop c 1

     setprop d 2

     setprop e 1

     setprop f 2

Services

是init加载起来的应用程序,并且程序退出时会重启。服务的格式如下

    service <name> <pathname> [ <argument> ]*

        <option>

        <option>

        ...

Options

Services的修饰符,决定了init什么时候,怎么运行这个service。

capabilities

参考https://man7.org/linux/man-pages/man7/capabilities.7.html

`class <name> [ <name>\* ]`

指定服务的类别,同一类别的class会一起启动和停止,例如class core;

如果没有指定就是default。

class `animation` 应该包含所有boot animation和shutdown animation的服务。所有这些服务可以在bootup阶段启动并且运行到shutdown的最后阶段。animation阶段不能保证/data分区没无法保证的。应用可以access文件,但不应该open /data下的文件,并且应该保证/data 分区不可用时可正常工作。

Class `console [<console>]` 表明服务需要一个console。第二个可选参数指定一个console代替默认的。默认的console "/dev/console" 可以被内核参数"androidboot.console"设置修改。/dev前缀被省略,所以想指定/dev/tty0,只需设置console tty0

`critical` 关键服务。如果这个服务在启动完成之前退出,或者4分钟内退出4次,将进入BootLoader。

`disabled` 表示这个服务不会随着 此类服务一起启动。需要通过接口或名字启动。

`enter_namespace <type> <path>`

进入path下的type namespace,目前type只支持net。

`file <path> <type>`

打开一个文件,并将fd给到进程,type必须是"r", "w" or "rw".对于native层应用,可以参考libcutils  android_get_control_file()函数。

`group <groupname> [ <groupname>\* ]`

服务运行前更改组名为groupname第二哥groupname表示附加组,通过setgroups()默认是root

`interface <interface name> <instance name>`

将此服务与提供的aidl hidl服务进行关联。例如用于servicemanager hwservicemanager启动lazily services   

例如:interface vendor.foo.bar@1.0::IBaz default

`ioprio <class> <priority>`

IO优先级,可以通过SYS_ioprio_set syscall设置,class必须是 "rt", "be", or "idle"_priority_  0 - 7

`keycodes <keycode> [ <keycode>\* ]`

设置按键触发,通常用于bugreporter。

`memcg.limit_in_bytes <value>` and `memcg.limit_percent <value>`

系统启动了memcgrooup时,设置子进程的内存限制。

`memcg.limit_property <value>`

`memcg.soft_limit_in_bytes <value>`

`memcg.swappiness <value>`

`namespace <pid|mnt>`

Fork这个服务时指定一个新的pid,或者mount一个namespace。

`oneshot`

这个程序退出时不重启它。

`onrestart`

当服务重启时,执行一个命令

`oom_score_adjust <value>`

设置value值到 /proc/self/oom\_score\_adj范围是 -1000 - 1000.

`override`

用于覆盖之前定义的同名服务,一般用于/odm 覆盖 /vendor的,init使用最后一个override定义的服务。

`priority <priority>`

进程调度优先级,-20 to 19默认是0,-20优先级更高。setpriority()

`restart_period <seconds>`

重启期间段;一个non-oneshot服务,从运行时开始计时,seconds秒后restart一次。默认是5s,防止服务频繁crash。可以用于周期性服务,例如3600 ,表示每1小时重启一次。

`rlimit <resource> <cur> <max>`

用于resource limit,这个限制会继承给子进程,所以rlimit是应用于一个进程树。命令解析方式可以参考setrlimit

`seclabel <seclabel>`

更改服务的 'seclabel'主要用于rootfs运行的服务使用,例如uevent、adbd.

`setenv <name> <value>`

服务运行时,设置环境变量到系统中。

`shutdown <shutdown_behavior>`

设置服务在关机时的行为。如果未指定,进程被SIGTERM and SIGKILL

如果设置了shutdown_behavior"critical"shutdown critical

进程在shutdown执行超时之前不会被kill掉,当shutdown timeout时,标记shutdown critical的服务也会被kill掉。设置shutdown critical时,如果关机进程启动时此服务不存在,就会启动此服务。

`sigstop`

在执行此服务之前先发送SIGSTOP 用于debug调试。

`socket <name> <type> <perm> [ <user> [ <group> [ <seclabel> ] ] ]`

创建一个unix domain socket 名字为/dev/socket/_name_,并把fd传给服务。_type_ 必须是 "dgram", "stream" or "seqpacket"User  group 默认 0.

'seclabel' 是这个socket的 SELinux security context

参考libcutils android_get_control_socket()

`timeout_period <seconds>`

在服务被kill掉时,延时多长时间。设置timeout_periodoneshot 设置还是有效的,也就是说不会restart。但没设置oneshot的服务会再seconds秒后restart。这个和restart_period 可以混合使用。

`updatable`

用于apex更新,一个服务带着`updatable`启动,在APEXes 完全激活之前,进程是delayed的。如果一个服务没有updatable就不能被APEXes 更新。

`user <username>`

程序执行前修改 'username' 默认是root。

`writepid <file> [ <file>\* ]`

写子进程的pid到文件,用于cgroup/cpuset如果writepid时, /dev/cpuset/下的文件不存在,但系统属性ro.cpuset.default是非空cpuset name例如'/foreground'这个pid就会写到/dev/cpuset/_cpuset\_name_/tasks.

Triggers

--------

触发器,让一个Action运行。分为event triggers property triggers

'trigger'命令和init中的 QueueEventTrigger() 属于event trigger。比如'boot' or 'late-init

Property triggers是当属性设置或发生变化时触发;形式是'property:<name>=<value>' and 'property:<name>=\*'

Property triggers在init的boot阶段,会额外触发。

一个Action可以有多个属性trigger,但只能有一个event trigger。

`on boot && property:a=b` d

`on property:a=b && property:c=d` d

Commands

--------

执行的命令

`bootchart [start|stop]`

Start/stop bootcharting

出现在默认的init.rc中,只有当 /data/bootchart/enabled存在时才有意义。

`chmod <octal-mode> <path>`

修改文件访问权限,和手动执行chmod没区别。

`chown <owner> <group> <path>`

修改文件的ownergroup

`class_start <serviceclass>`

启动某一类服务,比如class core

`class_start_post_data <serviceclass>`

`class_start <serviceclass>`差不多,只考虑在/data/分区mount之后才运行的服务,并且要class_reset_post_data调用之后。一般用于FDE devices

`class_stop <serviceclass>`

如果某类服务运行着,就stop并disable掉。

`class_reset <serviceclass>`

停止某类服务,但并不disable掉,只有还可以用class_start <serviceclass>启动。

`copy <src> <dst>`

理解为cp命令,对于src文件, symbolic link file and world-writable  or group-writable files是不允许的。对于dst文件,如果不存在,默认 0600权限,如果已经存在就会截断覆盖。

`domainname <name>`

设置domain name.

`enable <servicename>`

当一个服务没被设置为disable时,将这个服务设置为enable。如果一个预期需要运行,那enable servicename的服务就立即运行了。例如BootLoader设置一个属性要运行这个服务。

on property:ro.boot.myfancyhardware=1

        enable my_fancy_service_for_my_fancy_hardware

`exec [ <seclabel> [ <user> [ <group>\* ] ] ] -- <command> [ <argument>\* ]`

Fork并运行带参数的command,Init 暂停执行其它commands 直到command进程退出.

`exec_background [ <seclabel> [ <user> [ <group>\* ] ] ] -- <command> [ <argument>\* ]`

exec 差不多,当并不暂停执行其它命令。

`exec_start <service>`

启动一个服务并暂停init的其它command执行,和exec类似,只是把命令改为了服务名。

`export <name> <value>`

相当于export命令,export name=value,设置一个全局环境变量,在这之后运行的程序都可以访问到。

`hostname <name>`

设置host name

`ifup <interface>`

使network interface _interface_ online

`insmod [-f] <path> [<options>]`

Insmod path路径下的ko。Option是其选项,-f标志强制insmod,不管是否和内核版本匹配。

`load_system_props`

这个强烈不建议使用。

`load_persist_props`

在/data/解密之后加载persistent properties应该包含在默认的init.rc

`loglevel <level>`

设置内核loglevel等级

`mark_post_data`

用于mark /data挂载的时刻。用于`class_reset_post_data` and `class_start_post_data`

`mkdir <path> [mode] [owner] [group]`

创建path路径的文件夹,如果默认不带其它参数,mode是755 owner、group是root。

`mount_all <fstab> [ <path> ]\* [--<option>]`

调用 fs_mgr_mount_all mount fstab文件中的分区,option有late和early,详见前面的init.rc说明。

`mount <type> <device> <dir> [ <flag>\* ] [<options>]`

尝试挂载 dir 路径下的 device设备, _flag_s 包含"ro", "rw", "remount", "noatime", ...

 _options_ 包含"barrier=1", "noauto_da_alloc", "discard", ... 并用逗号‘,’分开,eg: barrier=1,noauto_da_alloc

`parse_apex_configs`

用于解析apex的配置,一般用在 apexd.status 属性设置时。

`restart <service>`

停止并重启此服务,如果正在重启中,不做任何事情,

`restorecon <path> [ <path>\* ]`

将 _path_ 命名的文件恢复到 file_contexts 中指定的安全上下文

`restorecon_recursive <path> [ <path>\* ]`

上边命令的递归恢复。

`rm <path>`

对path路径调用unlink(2)也可以用"exec -- rm ..."代替。

`rmdir <path>`

对path路径调用 rmdir(2)

`readahead <file|dir> [--fully]`

对file|dir调用readahead(2)--fully表示完整的读取整个内容。

`setprop <name> <value>`

设置属性名name值为value

`setrlimit <resource> <cur> <max>`

对某项资源的限制,对全局的进程有效。应该在init之前设置,比如设置'cpu', 'rtio''RLIM_CPU', 'RLIM_RTIO',设置'unlimited' or '-1'表示不限制。

`start <service>`

如果一个服务不是running就启动它。这个操作是不保证状态同步的,也就是同一时刻可能运行两次这个服务,可能存在冲突。

`stop <service>`

停止一个服务

`swapon_all <fstab>`

对fstab文件调用fs_mgr_swapon_all

`symlink <target> <path>`

对path创建一个软链接。

`sysclktz <mins_west_of_gmt>`

设置系统时钟基准,如果已GMT标准为0.

`trigger <event>`

触发一个event

`umount <path>`

Unmount the filesystem mounted at that path.

`verity_load_state`

 用于加载 dm-verity 状态的内部实现细节。

`verity_update_state <mount-point>`

用于加载 dm-verity 状态的内部实现细节和adb remount 设置属性partition._mount-point_.verified fs_mgr不直接操作。

`wait <path> [ <timeout> ]`

轮询给定文件是否存在,找到或超时返回。如果指定超时,默认为五秒。

`wait_for_prop <name> <value>`

等待属性name值为value,如果相等,立即执行。

`write <path> <content>`

对path路径的文件写content内容,相当于调用 write(2)Path不存在就创建,存在会被截断重写,相当与覆盖而不是追加。

Imports

-------

`import <path>`

导入path路径的rc文件给init解析,如果是一个文件夹,只解析当前路径下的所有rc文件,不会解析包含的子文件夹。

import关键字不是命令,而是它自己的部分,这意味着它不是作为Action的一部分发生,而是作为正在解析的文件处理导入,并遵循以下逻辑。

只有在以下三种情况下才导入rc文件。

  1. 导入/init.rc 或boot initail 时设置`ro.boot.init_rc`属性时,

2、在导入/init.rc后,first mount stage阶段导入{system,vendor,odm}/etc/init/ 时。

3、当mount_all指定路径时,导入指定路径/{system,vendor,odm}/etc/init/或.rc文件

由于兼容性和历史原因,import文件是一个复杂的问题,没法保证顺序。

只有两种方式可以保证一个服务运行于另一个服务之前。1、放在一个可以更早trigger的Action中运行,2、放在同一个文件同一个Action的更早行中执行。

first stage mount devices的顺序是:

1、/init.rc 然后递归解析import的rc文件,Android12+是 /system/etc/init/hw/init.rc

2、/system/etc/init/是按字母顺序导入的解析的,解析后递归执行。

3、再按照步骤2处理 /vendor/etc/init 然后处理/odm/etc/init

伪代码如下:

     fn Import(file)

       Parse(file)

       for (import : file.imports)

         Import(import)

 

     Import(/init.rc)

     Directories = [/system/etc/init, /vendor/etc/init, /odm/etc/init]

     for (directory : Directories)

       files = <Alphabetical order of directory's contents>

       for (file : files)

         Import(file)

Properties

----------

提供以下属性状态信息。

`init.svc.<name>`

Name服务的运行状态,("stopped", "stopping", "running", "restarting")

`dev.mnt.blk.<mount_point>`

块设备的挂载点,例如`dev.mnt.blk.root`

Boot timing

-----------

启动时序,init通过系统属性记录系统的启动时序。

`ro.boottime.init`

单位是ns,这个属性值记录的是init的FirstStageMain()函数结束,马上要执行secondstage了的时刻。First stage start启动完成的时间。

{

setenv("INIT_STARTED_AT", std::to_string(start_ms).c_str(), 1);

property_set("ro.boottime.init", getenv("INIT_STARTED_AT"));

}

`ro.boottime.init.selinux`

First stage start 阶段selinux SelinuxInitialize初始化耗时。

`ro.boottime.init.cold_boot_wait`

等待coldboot的时间,即等待文件"/dev/.coldboot_done"可用。

`ro.boottime.<service-name>`

service-name服务首次运行的时间,单位ns。

Bootcharting

-----------

这个一个Android系统提供的分析启动时间的工具,可以生成图表。可以再Ubuntu上配合分析工具可以使用。

设备上enable此功能

adb shell 'touch /data/bootchart/enabled'

Log文件在/data/bootchart/

sudo apt-get install pybootchartgui

     # grab-bootchart.sh uses $ANDROID_SERIAL.

     $ANDROID_BUILD_TOP/system/core/init/grab-bootchart.sh

Comparing two bootcharts

Usage: system/core/init/compare-bootcharts.py _base-bootchart-dir_ _exp-bootchart-dir_

Debugging init

--------------

一般无法手动启动init服务。因为它初始化了大量的环境。如果要一开始就调试服务,就使用`sigstop`选项,这样会在执行服务前发送SIGSTOP让你有机会使用strace命令调用attached它。

这个flag可以通过 ctl.sigstop_on ctl.sigstop_off 属性动态设置.

Below is an example of doing the same but with strace

 

     stop logd

     setprop ctl.sigstop_on logd

     start logd

     ps -e | grep logd

     > logd          4343     1   18156   1684 do_signal_stop 538280 T init

     strace -p 4343

 

     (From a different shell)

     kill -SIGCONT 4343

 

     > strace runs

Host Init Script Verification

-----------------------------

脚本的校验。

  1. 对于脚本中的action, service and import sectionsAction没有on触发机制,没有import的关联行。

2、所有命令都映射到有效的关键字,并且参数数量在正确的范围内。

3、所有服务选项均有效。这比检查服务命令的方式更严格选项的参数已被完全解析,例如UID 和 GID 必须解析。

也有一些脚本是运行时解析,不会在构建时检查;

  1. 参数的有效性不检查;例如文件是否存在,selinux是否允许这个操作,UID、GID是否允许解析。
  1. 不检查服务是否存在或是否定义了有效的 SELinux 域
  2.  不检查服务是否先前在不同的初始化脚本中定义过

Early Init Boot Sequence

------------------------

Early Init 启动顺序分为三个阶段:first stage init, SELinux setup,second stage init.

First stage init 阶段是初始化一个最低要求的环境,用于加载系统其余部分。具体来说,包含mount /dev, /proc, mounting 'early mount' partitions (包含系统代码的所有分区,例如system,vendor),对于有ramdisk的设备,将system.img挂载早/目录。

 Android Q 中,system.img始终包含 TARGET_ROOT_OUT,并且始终由First stage init阶段初始化完成的时间。Android Q 还需要动态分区,因此

需要使用 ramdisk 来启动 Android。

根据设备配置,First stage init有三种变化:

通用场景

术语库

1)对于system-as-root设备,第一阶段init是/system/bin/init的一部分,为了向后兼容,/init上的符号链接指向/system/bin/init。这些设备不需要做任何事情来安装系统。Img,因为根据定义,它已经被内核挂载为根文件。

2)对于带有ramdisk的设备,第一阶段init是位于/init的静态可执行文件。这些设备挂载系统。Img /system然后执行切换根操作,将挂载在/system的挂载移动到/。挂载完成后释放ramdisk的内容。

3)对于使用recovery作为ramdisk的设备,首先将其初始化包含在位于恢复ramdisk /init的共享init中。这些设备首先将root切换到/first_stage_ramdisk从环境中删除恢复组件,然后进行与2)相同的操作。请注意,如果androidboot,则决定正常引导到Android而不是引导到恢复模式。中存在Force_normal_boot =1内核命令行。

first stage init结束后,执行 /system/bin/init  selinux_setup.

selinux_setup结束后, 执行 /system/bin/init  second_stage这是main的主阶段执行,继续通过rc文件启动脚本。

启动顺序:

在init second stage阶段,会trigger early-init,initlate-init

am.QueueEventTrigger("early-init");

am.QueueEventTrigger("init");

am.QueueEventTrigger("late-init");

就会执行init.rc中的

on early-init

on init

on late-init

    trigger post-fs      

    trigger load_system_props_action

    trigger post-fs-data  

    trigger load_persist_props_action

    trigger firmware_mounts_complete

trigger boot

上面是init源码中调用的,下面是trigger触发的。

on post-fs      //挂载文件系统

    start logd

    mount rootfs rootfs / ro remount

    mount rootfs rootfs / shared rec

    mount none /mnt/runtime/default /storage slave bind rec

    ...

on post-fs-data  //挂载data

    start logd

    start vold   //启动vold

    ...

on boot      //启动核心服务

    ...

    class_start core //启动core class

汇总:触发器的执行顺序为on early-init -> init -> late-init,从上面的代码可知,在late-init触发器中会触发文件系统挂载以及on boot。再on boot过程会触发启动core class。至于main class的启动是由vold.decrypt的以下4个值的设置所决定的, 该过程位于system/vold/cryptfs.c文件。

on nonencrypted

    class_start main

    class_start late_start

on property:vold.decrypt=trigger_restart_min_framework

    # A/B update verifier that marks a successful boot.

    exec_start update_verifier

    class_start main

on property:vold.decrypt=trigger_restart_framework

    # A/B update verifier that marks a successful boot.

    exec_start update_verifier

    class_start_post_data hal

    class_start_post_data core

    class_start main

    class_start late_start

    setprop service.bootanim.exit 0

    start bootanim

Android Display Graphics系列文章-汇总

系列文章请扫关注公众号!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1947229.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot集成Tomcat、DispatcherServlet

通过 SpringBoot 自动配置机制&#xff0c;导入配置类 利用 SpringBoot 自动配置机制&#xff0c;SpringBoot 会导入一个类型为 ServletWebServerFactoryAutoConfiguration 的配置类 ServletWebServerFactoryAutoConfiguration ServletWebServerFactoryAutoConfigurations 类上…

软考中级网络工程师考什么?应该怎么正确备考

网络工程师软考中级难易度50%&#xff0c;不太难。但是如果准备不足就悬了&#xff0c;赶紧备考起来吧。 网络工程师每年考两次&#xff0c;相比其他的软考考试一年中考的机会又多了一次&#xff0c;而且软考网工也是挺热门的科目&#xff0c;每年很多人报考&#xff0c;相对的…

CoAP——Libcoap安装和使用(Ubuntu22.04)

1、简介 CoAP&#xff08;Constrained Application Protocol&#xff09;是一种专为受限设备和网络设计的应用层协议。它类似于HTTP&#xff0c;但具有更轻量级的特性&#xff0c;适合用于物联网&#xff08;IoT&#xff09;环境中的低功耗和低带宽设备。Libcoap是一个轻量级的…

RK3568 Linux 平台开发系列讲解(内核入门篇):如何高效地阅读 Linux 内核设备驱动

在嵌入式 Linux 开发中,设备驱动是实现操作系统与硬件之间交互的关键。对于 RK3568 这样的平台,理解和阅读 Linux 内核中的设备驱动程序至关重要。 1. 理解内核架构 在阅读设备驱动之前,首先要了解 Linux 内核的基本架构。内核主要由以下几个部分组成: 内核核心:处理系…

源码拆解SpringBoot的自动配置机制

SpringBoot相比于Spring系列的前作&#xff0c;很大的一个亮点就是将配置进行了简化&#xff0c;引入了自动化配置&#xff0c;仅靠几个注解和yml文件就取代了之前XML的繁琐配置机制&#xff0c;这也是SpringBoot的独有特点&#xff0c;下面我们从源码角度&#xff0c;一点点拆…

Linux_实现TCP网络通信

目录 1、实现服务器的逻辑 1.1 socket 1.2 bind 1.3 listen 1.4 accept 1.5 read 1.6 write 1.7 服务器代码 2、实现客户端的逻辑 2.1 connect 2.3 客户端代码 3、实现服务器与客户端的通信 结语 前言&#xff1a; 在Linux下&#xff0c;实现传输层协议为TCP…

Oracle配置TCPS加密协议测试

文章目录 一、环境信息二、配置过程1.创建证书2.监听配置2.1.配置sqlnet.ora2.2.配置listener.ora文件2.3.配置tnsnames.ora文件2.4.重载监听 3.数据库本地测试3.1. tcps登录测试3.2.日志监控 一、环境信息 操作系统&#xff1a;Linux 版本信息&#xff1a;Oracle 19c 参考文档…

威联通启用SFTP并安装内网穿透工具实现远程管理家中NAS中的资源

文章目录 前言1. 威联通NAS启用SFTP2. 测试局域网访问3. 内网穿透安装配置3.1 威联通安装cpolar内网穿透3.2 创建隧道3.3 测试公网远程访问 4. 配置固定公网TCP端口地址4.1 保留一个固定TCP端口地址4.2 配置固定TCP端口地址4.3 测试使用固定TCP端口地址远程连接威联通SFTP 前言…

怎么使用github上传XXX内所有文件

要将 目录中的所有文件上传到 GitHub&#xff0c;你可以按照以下步骤进行&#xff1a; 创建一个新的 GitHub 仓库 登录到你的 GitHub 账户。 点击右上角的加号&#xff08;&#xff09;&#xff0c;选择 “New repository”。 输入仓库名称&#xff08;例如&#xff1a;202407…

【Python】Facebook开源时间序列数据预测模型Prophet

文章目录 一、简介二、项目的文件解读三、Prophet类主要方法和参数3.1 主要参数3.2 主要方法 四、用法示例 一、简介 Prophet 是由 Facebook 开发的一个开源工具&#xff0c;用于时间序列数据的预测。它特别适用于处理具有强季节性和趋势的时间序列数据&#xff0c;并且对节假…

代码审计 | .NET SqlSugar框架注入漏洞

01阅读须知 此文所节选自小报童《.NET 代码审计》专栏&#xff0c;主要内容有涉及的.NET目录和文件操作、SQL注入方向的敏感函数、还有不安全的配置导致的漏洞挖掘思路&#xff0c;对.NET代码审计感兴趣的朋友们可以解锁该电子报刊&#xff0c;解锁更多的报刊内容。 02基本介…

央国企改革关键年!契约锁电子签章助力业务全程数字化场景落地

契约锁作为行业领先的电子签及印控厂商已经服务了400多家大型央企、国企单位&#xff0c;其中国资委下属的98家一级央企&#xff0c;近三分之一选择使用契约锁。 央国企改革新三年计划已实施过半&#xff0c;改革进入关键之年&#xff0c;全国各地央国企全面发力、加快数字化建…

技术成神之路:设计模式(九)观察者模式

介绍 观察者模式&#xff08;Observer Pattern&#xff09;是一种行为设计模式。它允许一个对象&#xff08;称为主题或可观察者&#xff09;来监视并通知一组依赖于这个对象的其他对象&#xff08;称为观察者&#xff09;&#xff0c;以便在主题状态发生变化时自动更新观察者的…

python机器学习8--自然语言处理(1)

1.基本定义&#xff1a; 语义&#xff1a;就是一句话的重点是什么。 自定词汇&#xff1a;因为语言、文字太多&#xff0c;自定和处理你所关心的重点词汇。 简体转繁体代码 from opencc import OpenCCtext1 "我去过清华大学" openCC OpenCC(s2t) line openCC.…

【系统架构设计师】计算机组成与体系结构 ⑯ ( 奇偶校验码 | CRC 循环冗余码 | 海明码 | 模 2 除法 )

文章目录 一、校验码1、校验码由来2、奇偶校验码3、CRC 循环冗余码 ( 重点考点 )4、海明码校验 ( 软考不经常考到 ) 二、CRC 循环冗余码 ( 重点考点 )1、模 2 除法概念2、模 2 除法步骤3、模 2 除法示例4、CRC 循环冗余码示例 15、CRC 循环冗余码示例 2 参考之前的博客 : 【计…

基于微信小程序的自习室选座系统/基于Java的自习室选座系统/自习室管理系统的设计与实现

获取源码联系方式请查看文章结尾&#x1f345; 摘要 自习室选座是学校针对用户必不可少的一个部分。在学校的整个过程中&#xff0c;学生担负着最重要的角色。为满足如今日益复杂的管理需求&#xff0c;各类微信小程序自习室选座也在不断改进。本课题所设计的小程序自习室选座系…

npm下载pnpm

一、提供node_global和node_cache的文件夹 若不存在&#xff0c;可自行新建文件夹 二、配置环境变量 配置NODE_PATH变量&#xff1a; 配置Path变量&#xff1a; 三、执行cmd指令 npm config set prefix "D:\Configure\nodejs\node_global" npm config set cache &…

cdga|数据治理难题破解:策略与实施路径

随着信息技术的飞速发展&#xff0c;数据已成为企业最宝贵的资产之一。然而&#xff0c;数据治理的复杂性也随之增加&#xff0c;如何有效管理、保护和利用数据成为摆在企业面前的一大难题。本文将从数据治理的挑战入手&#xff0c;探讨其破解策略与实施路径。 数据治理的挑战 …

华为IoTDA平台下发MQTT消息

前一篇博文介绍了如何使用MQTTX连接华为IoTDA平台并上报消息&#xff0c;本文介绍一下如何下发消息。 IoT设备接入平台支持MQTT协议设备进行命令下发&#xff0c;属性设置&#xff0c;属性查询以及消息下发等操作。 在进入指定设备的页面后&#xff0c;选择“云端下发”&#…

洛谷 P9854 [CCC 2008 J1] Body Mass Index

这题让我们计算出 BMI 值&#xff0c;随后判断属于哪个等级。 BMI 值计算公式&#xff1a; ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​。 BMI 范围 对应信息 …