docker 网络(单机环境)
文章目录
- 深入理解 Namespace
- 什么是Namespace
- Namespace当中的 Network Namespace
- Libcontainer
- docker 网络基础
- 创建两个命名空间
- 创建网络接口 veth pair
- 命名空间添加 veth 接口
- 为 veth 接口分配 IP
- 启动 veth 接口
- 相互 ping
- bridge 网络
- 搭建网络环境
- 查看docker0 网桥
- 创建网桥 bridge2
- 创建容器并连接网络
- 查看容器详情
- 查看网络详情
- 容器之间相互ping
- ping 容器名
- 创建定向连接容器
- 创建共享网络命名空间容器
- none 网络
- 创建 none 网络容器
- 查看容器详情
- host 网络
- 创建 host 网络容器
- 查看容器详情
- 查看容器的IP信息
深入理解 Namespace
什么是Namespace
-
先来看看那种比较正式的定义。Namespace是将内核的全局资源做封装,使得每个Namespace都有一份独立的资源,因此不同的进程在各自的Namespace内对同一种资源的使用不会互相干扰。
-
这样的解释可能不清楚。举个例子:在Linux系统上,你想要改变系统的主机名,这个主机名就是一个内核的全局资源。但是内核通过实现UTS Namespace,可以将不同的进程分隔在不同的UTS Namespace中,在某个Namespace修改主机名时,另一个Namespace的主机名还是保持不变。
-
所以说Namespace是用来隔离进程对系统资源的访问。每一个 Namespace 都有一套自己的系统资源(例如进程ID、主机名、网络接口等),进程只能看到和操作同一个 Namespace 中的资源。这样就可以在逻辑上隔离不同的进程,让它们在各自的 “空间” 中运行,互不干扰。
-
在 Linux 系统中,每个进程都与一组 Namespace 关联。这些 Namespace 决定了进程可以看到和影响哪些系统资源。例如,进程的网络 Namespace 决定了进程可以看到和使用哪些网络接口。
-
当一个进程被创建时,它会继承其父进程所在的所有 Namespace。但是,也可以在创建新进程时指定其所在的 Namespace,或者将已有的进程移动到新的Namespace。在 Linux 的 /proc 文件系统中,可以查看进程的 Namespace 信息。例如,/proc/[pid]/ns/ 目录下的每个文件都代表了一个 Namespace,这些文件是该进程所在 Namespace 的符号链接。通过查看和比较这些文件,可以确定进程的 Namespace 信息。
看完上面5段话,对于Namespace就会有一个基本的认识。
Namespace当中的 Network Namespace
目前Linux内核总共实现了6种 Namespace。
- IPC:隔离System V IPC和 POSIX消息队列。
- Network:隔离网络资源。
- Mount:隔离文件系统挂载点。
- PID:隔离进程ID。
- UTS:隔离主机名和域名。
- User:隔离用户ID和组ID。
Network Namespace 对网络相关的系统资源进行隔离,每个Network Namespace都有自己的网络设备、IP地址、路由表、/proc/net目录、端口号等。网络隔离的必要性是很明显的举一个例子,在没有隔离的情况下,如果两个不同的容器都想运行同一个Web应用,而这个应用又需要使用80端口,那就会有冲突了。
Libcontainer
Libnetwork是由Go语⾔编写的一个开源工具,该工具具有跨平台性,主要处理Docker网络相关的工作。下图是Libnetwork的整体结构。
- 沙盒:沙盒是一个隔离的网络运行环境,保存了容器网络栈的配置,包括了对网络接口、路由表和 DNS配置的管理。在 Linux平台上,沙盒是用Linux NetworkNamespace实现的。一个沙盒可以包括来自多个网络的多个Endpoint(网络接口)。
- 网络接口:Endpoint(网络接口)将沙盒加入一个网络,Endpoint 的实现可以是一对 veth pair或者OVS内部端口,当前的Libnetwork 使用的是veth pair。一个 Endpoint 只能属于一个沙盒及一个网络。通过给沙盒增加多个Endpoint可以将一个沙盒加入多个网络。
- 网络:网络包括一组能互相通信的Endpoint。网络的实现可以是bridge ,host,none等。
- 可拔插接口:可拔插接口指的是允许开发者将自定义的网络驱动接入到 Libnetwork 中,使得 Docker 容器可以使用这些自定义的网络驱动进行网络通信。这种接口的设计使得 Libnetwork 具备了极高的灵活性和可扩展性。
- 服务发现:Libnetwork 的网络控制层和管理层负责创建和管理网络以及网络接口。这些网络接口可以被绑定Docker 容器上,使得这些容器可以在同一个网络中相互通信。通过这种方式,容器可以实现本地服务发现,即在同一个网络中的容器可以通过容器名称或者其他标识来找到其他容器,从而实现相互通信。
- 负载均衡:Libnetwork 的网络控制层和管理层可以创建和管理网络,这些网络可以配置为支持负载均衡。例如,可以使用 Overlay 网络驱动创建一个跨多个 Docker 宿主机的虚拟网络,然后在这个虚拟网络中的容器之间实现负载均衡。另外,Libnetwork 还可以与 Docker Swarm 集群管理工具集成,通过 Docker Swarm,可以实现在集群范围内的容器负载均衡。
docker 网络基础
有了上面的一些基础知识做铺垫,理解docker 网络的底层原理可能会轻松一点。下面就用一些linux命令创建两个命名空间,最后让这两个命名空间之间能相互通信。
创建两个命名空间
分别创建两个命名空间 namespace1 与 namespace2。
因为每个网络空间都是独立的,所以每个 Network Namespace 都具有一个回环网络适配器 lo。可以看到这个接口的最大传输单元(MTU)是65536字节,其中MTU是网络接口可以接受的最大数据包大小。并且还可以看到state DOWN表示这个接口目前没有启用。而qlen 1000则表示这个接口的发送队列的长度,即接口可以缓存的待发送数据包的数量。
创建网络接口 veth pair
如果要让两个命名空间连通,则需要用到虚拟设备接口技术 veth pair。该技术需要一对网络接口分别置于两个命名空间中。
以下命令用于创建一对网络接口 veth-ns1 与 veth-ns2。
对于ip link add veth-ns1 type veth peer name veth-ns2 这个命令的解释如下:
ip link add
:这是用于创建网络设备的命令。veth-ns1
:这是你要创建的第一个veth设备的名称。type veth
:这表示你要创建的设备的类型是 veth。peer name veth-ns2
:这表示你要创建的第二个veth设备的名称。peer
关键字表示这两个设备是一对,互为对方的端点。
而 ip link show veth-ns1命令和 ip link show veth-ns2 命令展示了两个虚拟网络接口的信息。通过 veth-ns1@veth-ns2 和 veth-ns2@veth-ns1 可以发现这两个网络接口是一对接口。除此之外,还能看到网络接口的状态和MAC地址等等信息。
命名空间添加 veth 接口
通过 ip link set 命令,将这两个网络接口分别分配给两个命名空间。
为 veth 接口分配 IP
前面创建的两个网络接口是没有 IP 的。下面要通过 ip netns exec 命令,为每个指定的命名空间执行 IP 添加命令 ip addr add [ip] dev [网络接口]。为 namespace1 的 veth-ns1 网络接口分配的 IP 为 192.168.1.1,掩码为 24;为 namespace2 的 veth-ns2 网络接口分配的 IP 为 192.168.1.2,掩码为 24。
启动 veth 接口
以上两个命名空间中的 veth 接口已经具有了 IP,但其状态仍为 DOWN,还没有开启。下面要通过 ip link set dev [接口] up 来启动指定的网络接口。
相互 ping
此时可以通过在两个命名空间中执行 ping 命令来与对方进行连通性测试了。
bridge 网络
通过 docker network ls 命令可以查看当前主机所连接的网络及网络类型。
bridge 网络,也称为单机桥接网络,是 Docker 默认的网络模式。该网络模式只能存在于单个 Docker 主机上,其只能用于连接所在 Docker 主机上的容器。
搭建网络环境
需求:搭建如下的网络环境。
查看docker0 网桥
- 网络接口名称(docker0)及其状态(UP,表示启动并运行)。
- docker0 的 MAC 地址(02:42:36:20:cc:8b)。
- docker0 的 IP 地址(172.17.0.1)和子网掩码(/16,表示子网的地址范围是 172.17.0.0 到 172.17.255.255)。
- docker0 的广播地址(172.17.255.255)。
- docker0 的 IPv6 地址(fe80::42:36ff:fe20:cc8b/64)。
- docker0 的 MTU(Maximum Transmission Unit,最大传输单元)是 1500。这是 Ethernet 的标准 MTU。
创建网桥 bridge2
-d 选项用于指定要创建网络时所使用的驱动,即创建的网络类型。最后的 bridge2 则是新创建网络的名称。查看bridge2网桥的相关信息:
可以看到bridge2网桥的IP地址为172.18.0.1。
创建容器并连接网络
创建busybox1容器并连接bridge网桥:--network bridge
告诉 Docker 使用 bridge
网桥来运行 busybox1
容器。
可以看到busybox1的IP地址为172.17.0.2。现在创建busybox2容器并连接bridge网桥。
可以看到busybox2容器的IP地址为172.17.0.3。现在要将busybox2连接到bridge2网桥上。
使用docker network connect命令就可以让busybox2容器连接到bridge2网桥上。可以发现busybox2的IP地址又多了一个172.18.0.2/16。说明这个IP地址在172.18.0.0这个网段上,也就是bridge2网桥所在的网段。现在创建busybox3容器并连接到bridge2网桥上。
可以看到busybox3的IP地址为172.18.0.3。
查看容器详情
这里以busybox2容器为例,查看该容器的网络详情。
docker inspect busybox2# 查看容器的网络配置信息:NetworkSettings
{"Bridge": "", "SandboxID": "145b13df0a94364eda70a3dd93a10b171f23159ddff200313f4a0c558505b9e6", "HairpinMode": false, "LinkLocalIPv6Address": "", "LinkLocalIPv6PrefixLen": 0, "Ports": { }, "SandboxKey": "/var/run/docker/netns/145b13df0a94", "SecondaryIPAddresses": null, "SecondaryIPv6Addresses": null, "EndpointID": "2af54e966620633d28dfc91e54816e4a85a4c105c0213a7ef41d2c9fdcf2f3df", "Gateway": "172.17.0.1", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "IPAddress": "172.17.0.3", "IPPrefixLen": 16, "IPv6Gateway": "", "MacAddress": "02:42:ac:11:00:03", "Networks": {"bridge": {"IPAMConfig": null, "Links": null, "Aliases": null, "NetworkID": "5f417d52f8fdae77a94202c473b03e1998de09f7509363e03826c01a3f669f14", "EndpointID": "2af54e966620633d28dfc91e54816e4a85a4c105c0213a7ef41d2c9fdcf2f3df", "Gateway": "172.17.0.1", "IPAddress": "172.17.0.3", "IPPrefixLen": 16, "IPv6Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "MacAddress": "02:42:ac:11:00:03", "DriverOpts": null}, "bridge2": {"IPAMConfig": { }, "Links": null, "Aliases": ["8be8f43ccd8d"], "NetworkID": "5f4893ee055e6a11841ff89b5a6b8d088d8d80362deac9f4c1ff0ee9d6974b96", "EndpointID": "c29ec9f1b1a75010c70a5f908175101bcbfc21b0159b3475fe7d7e50f86c3741", "Gateway": "172.18.0.1", "IPAddress": "172.18.0.2", "IPPrefixLen": 16, "IPv6Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "MacAddress": "02:42:ac:12:00:02", "DriverOpts": { }}}
}
可以看到busybox2这个容器有两个网段,分别是172.17.0.1和172.18.0.1;并且busybox2这个容器有两个IP地址,分别是172.17.0.3和172.18.0.2。
查看网络详情
# 查看网桥的相关信息
docker network inspect bridge2"Containers": {"8be8f43ccd8d1177bab90f81f3499f2448bfdc046c06db298f3e39f3943a5147": {"Name": "busybox2","EndpointID": "a7ecc7cf1092e7c7601ac14b560a43b648cde38d02ffe770ba9ec77a33b0de95","MacAddress": "02:42:ac:12:00:02","IPv4Address": "172.18.0.2/16","IPv6Address": ""},"97cbf3344e7b5587ce84ac0141af9a4b40692dd14407fc2ac40f20bf5f02456c": {"Name": "busybox3","EndpointID": "29cc4737c14c54b1b8a4698c66faa833e6262b4163152ee50b3ef6c7969228c0","MacAddress": "02:42:ac:12:00:03","IPv4Address": "172.18.0.3/16","IPv6Address": ""}}
查看 bridge2 的网络详情中的容器情况,发现 busybox2 与 busybox3 都在该网络上。
容器之间相互ping
发现busybox1能ping通busybox2;busybox2能Ping通busybox3;而busybox1不能ping通busybox3。说明只有在同一段网络下的容器之间才能相互ping通。
ping 容器名
该方式在生产中非常重要。因为生产中容器的 IP 可能会发生变化,但容器名称一般是不会变的。如果某服务总是直接通过 IP 与容器相连接,那么一旦容器 IP 变化,则该服务将连接不上容器。但如果是通过容器名称相连接的,那么无论容器 IP 如何变化,都将不影响服务与容器的连接。
创建定向连接容器
对于自定义的 bridge 网络,其具有一个特性:该网络上的容器可以通过容器名互 ping。但默认的 bridge 网络是不行的。如果在默认的 bridge 网络上实现通过容器名进行的连接,则需要创建容器时通过–link 选项指定。
但是容器 busybox4 是无法通过容器名称来连接 busybox2 的。然后 busybox1 也无法通过容器名称连接 busybox4。所以,–link 指定的连接是一种定向连接,是带有指向性与方向性的。
创建共享网络命名空间容器
在创建容器时可以指定其与某已经存在的容器共享 Network Namespace,但要求该已经存在的容器采用的是 bridge 网络模式。
docker run -it --name busybox-1 --network container:busybox1 busybox /bin/sh
上面的命令创建了一个 busybox-1 的容器,其共享了 busybox1 容器的 Network Namespace。查看两个容器的接口情况,发现完全相同。
查看容器 busybox-1 的详情,可以发现,其没有自身的网络设置。因为其共享的 bb1 容器的网络设置。
none 网络
none 网络,即没有网络。容器仍是一个独立的 Network Namespace,但没有网络接口,没有 IP。
创建 none 网络容器
在 docker run 命令中,通过–network none 选项指定创建的容器没有网络功能。
docker run -it --name busybox5 --network none busybox /bin/sh
查看容器详情
# 查看容器详情的命令
docker inspect busybox5# 下面是busybox5关于网络部分的信息
"NetworkSettings": {"Bridge": "","SandboxID": "400b397e12ca82bc791f5fd4d194a05289445e489a121e2fce06ca54817f2f86","HairpinMode": false,"LinkLocalIPv6Address": "","LinkLocalIPv6PrefixLen": 0,"Ports": {},"SandboxKey": "/var/run/docker/netns/400b397e12ca","SecondaryIPAddresses": null,"SecondaryIPv6Addresses": null,"EndpointID": "","Gateway": "","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"IPAddress": "","IPPrefixLen": 0,"IPv6Gateway": "","MacAddress": "","Networks": {"none": {"IPAMConfig": null,"Links": null,"Aliases": null,"NetworkID": "3b0eaed4d1d8ff72e62cc883d3a97639284fbd8eec96d6919322acbb4acd8d17","EndpointID": "61ed43896cfc51adf35120c16f335ba58dcb124103cb0bb6f17b7b9eee2ca355","Gateway": "","IPAddress": "","IPPrefixLen": 0,"IPv6Gateway": "","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"MacAddress": "","DriverOpts": null}}
}
通过 docker inspect 命令查看该容器的详情,发现其没有 IP,没有网关,没有 MAC 地址。这种none网络的主要用途是为那些不需要或不希望有任何网络通信功能的容器提供一个安全的运行环境,例如一些只需要进行本地计算或处理本地数据的应用。
host 网络
host 网络,即与宿主机 host 共用一个 Network Namespace。该网络类型的容器没有独立的网络空间,没有独立的 IP,全部与 host 共用。
创建 host 网络容器
在 docker run 命令中,通过–network host 选项指定创建的容器为 host 网络。
docker run -it --name busybox6 --network host busybox /bin/sh
查看容器详情
# 查看容器详情的命令
docker inspect busybox6# 下面是busybox5关于网络部分的信息
"NetworkSettings": {"Bridge": "","SandboxID": "d16a68fa18c745642fe4a7833e89bb2ee7351c06291cb5441dc3c35f7c350321","HairpinMode": false,"LinkLocalIPv6Address": "","LinkLocalIPv6PrefixLen": 0,"Ports": {},"SandboxKey": "/var/run/docker/netns/default","SecondaryIPAddresses": null,"SecondaryIPv6Addresses": null,"EndpointID": "","Gateway": "","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"IPAddress": "","IPPrefixLen": 0,"IPv6Gateway": "","MacAddress": "","Networks": {"host": {"IPAMConfig": null,"Links": null,"Aliases": null,"NetworkID": "16501fad09abfb197b94593aa27568c6c91cfbebb2c521553da481552fa3ad1f","EndpointID": "7cdf57ebf08f15fe7069b7f03f46a711b6b283ae8aff85ed614b6b5524dc9035","Gateway": "","IPAddress": "","IPPrefixLen": 0,"IPv6Gateway": "","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"MacAddress": "","DriverOpts": null}}
}
通过 docker inspect 命令查看该容器的详情,发现其没有 IP,没有网关,没有 MAC 地址。
查看容器的IP信息
通过 docker exec busybox6 ip addr 命令查看容器的IP信息可以发现该容器的IP与宿主机的IP信息一模一样。所以在host模式下,容器直接使用宿主机的网络接口、IP和路由规则。这意味着在host网络模式下运行的容器可以直接监听宿主机上的所有网络端口,也正是因为容器与宿主机共用网络端口,所以在host模式下的运行容器不需要进行端口映射就能直接对外提供服务。
这种模式的主要用途是为那些需要直接访问宿主机网络环境或者需要高性能网络通信的容器提供一个高效的运行环境。但是,由于它会让容器直接暴露在宿主机的网络环境中,所以在某些需要隔离或安全的场景中可能不适用。
相关文章:
docker 网络(单机环境)
文章目录 深入理解 Namespace什么是NamespaceNamespace当中的 Network Namespace Libcontainerdocker 网络基础创建两个命名空间创建网络接口 veth pair命名空间添加 veth 接口为 veth 接口分配 IP启动 veth 接口相互 ping bridge 网络搭建网络环境查看docker0 网桥创建网桥 br…...
14、二叉树的morris遍历等
统计热词 有一个包含100亿个URL的大文件,假设每个URL占用64B,请找出其中所有重复的URL 【补充】 某搜索公司一天的用户搜索词汇是海量的(百亿数据量),请设计一种求出每天热门Top100 词汇的可行办法 多个小文件的大根堆,然后把每…...
BeanFactory与ApplicationContext
BeanFactory与ApplicationContext的区别 使用Alt Ctrl U查看java类图 什么是BeanFactory接口 他是ApplicationContext的父接口他才是Spring 的核心容器,主要的ApplicationContext功能的实现都间接通过BeanFactory接口来实现 在ApplicationContext类中方法的实现是…...
【计算机网络】 粘包问题
文章目录 为什么会产生粘包问题?解决办法先发包大小再发包内容代码示例 为什么会产生粘包问题? tcp是数据流传输,是一种没有边界的,可以合并的传输数据方式。合并就要能拆开,拆不开就是粘包。 解决办法 设置标志位&a…...
valgrind massif 详解(内存分配释放分析)
参考 https://valgrind.org/docs/manual/ms-manual.html 使用格式 valgrind --toolmassif [--massif-opts] prog [prog-args]目的 记录每一次的malloc, free; 概念: malloc申请内存, 实际分配内存(字节对齐, 分配器的记录头, 等等原因) 对内存进行分析, 优化, 以达到资源…...
使用命令行创建一个vue项目卡住不动如何解决
问题 在使用命令去创建一个vue项目, 出现下面卡住不动的一个状态。 解决方案一 首先先ctrlc停止进入创建好的项目文件手动输入npm install 、npm run dev如果npm run dev 的时候 出现 ‘vite’ 相关的错误查看node版本是否是最新的稳定版本node -v查看安装源是否…...
七天学会C语言-第一天(C语言基本语句)
一、固定格式 这个是C程序的基本框架,需要记住!!! #include<stdio.h>int main(){return 0; }二、printf 语句 简单输出一句C程序: #include<stdio.h> int main(){printf("大家好,&quo…...
vue项目部署,出现两个ip的原因
我宁愿靠自己的力量打开我的前途,而不愿求有力者的垂青。——雨果 tags: 篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue项目部署,出现两个ip的原因相关的知识,希望对你有一定的参考价值。 参考技术A 在部署v…...
无涯教程-JavaScript - ASIN函数
描述 ASIN函数返回给定数字的反正弦或反正弦,并返回以弧度表示的Angular,介于-π/2和π/2之间。 语法 ASIN (number)争论 Argument描述Required/OptionalNumberThe sine of the angle you want and must be from -1 to 1.Required Notes 如果您希望ASIN函数返回的Angular以…...
MYSQL的SQL优化
insert语句 开启事务 手动控制事务 start transaction; insert into tb_test values(1,Tom),(2,Cat),(3,Jerry); insert into tb_test values(4,Tom),(5,Cat),(6,Jerry); insert into tb_test values(7,Tom),(8,Cat),(9,Jerry); commit; 内存插入 load命令中用 fields te…...
lintcode 553 · 炸弹袭击【中等 数组+bfs+模拟】
题目 https://www.lintcode.com/problem/553 给定一个二维矩阵, 每一个格子可能是一堵墙 W,或者 一个敌人 E 或者空 0 (数字 0), 返回你可以用一个炸弹杀死的最大敌人数. 炸弹会杀死所有在同一行和同一列没有墙阻隔的敌人。 由于墙比较坚固,所以墙不会被摧毁.你只…...
第一章 计算机系统概述 八、虚拟机
目录 一、传统虚拟机的结构 二、两类虚拟机管理程序 (1)定义: (2)区别:(考点) 一、传统虚拟机的结构 二、两类虚拟机管理程序 (1)定义: &…...
桶装水送水多水站送水员公众号h5开发
桶装水送水多水站送水员公众号h5开发 界面简洁易懂用户容易接受。 独家一户一码全家都能订水。 多个水站运营可按距离选择绑定。 三种支付方式水票、微信、到付。 强大员工系统老板坐享其成。 自由跑跑模式可招兼职送水员接单。 一户一码、全家享用 一户一码,精准…...
【JavaEE】多线程(二)
多线程(二) 文章目录 多线程(二)第一个多线程程序观察线程sleep创建线程继承Thread类,重写run方法实现Runnable, 重写run继承Thread,重写run实现Runnable,重写run基于lambda表达式 T…...
OkHttp 根据服务器返回的的过期时间设置缓存
据返回的缓存时间来缓存响应,可以通过使用OkHttp的CacheControl和ResponseCacheInterceptor来实现。以下是一个示例代码: // 创建缓存目录和缓存对象 File cacheDirectory new File(context.getCacheDir(), "http-cache"); int cacheSize 1…...
智能远程监考方案助力企业考试化繁为简
在音视频数字化之旅中,轻装上阵。 近年来,在数字化浪潮之下,远程考试频繁成为各领域热词,各企业也纷纷改革求新,将原本的企业内部考试转移到线上,从而获取更低廉的组考成本,更高的管理效率&…...
基于matlab实现的额 BP神经网络电力系统短期负荷预测未来(对比+误差)完整程序分享
基于matlab实现的额 BP神经网络电力系统短期负荷预测 完整程序: clear; clc; %%输入矢量P(15*10) P[0.2452 0.1466 0.1314 0.2243 0.5523 0.6642 0.7105 0.6981 0.6821 0.6945 0.7549 0.8215 0.2415 0.3027 0; 0.2217 0.1581 0.1408 0.23…...
WPF的_Expander控件
WPF Expander 是 WPF(Windows Presentation Foundation)框架中的一个控件,用于实现可以展开和折叠内容的可折叠面板。 Expander 控件通常由一个展开/折叠的标题(Header)和一个显示/隐藏的内容部分(Content…...
【MT7628AN】IOT | MT7628AN OpenWRT开发与学习
IOT | MT7628AN OpenWRT开发与学习 时间:2023-06-21 文章目录 `IOT` | `MT7628AN` `OpenWRT`[开发与学习](https://blog.csdn.net/I_feige/article/details/132911634?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22132911634…...
基于Matlab实现自动泊车(垂直泊车)
自动泊车是一项非常有趣和实用的技术,它可以让车辆在没有人为干预的情况下自动停放在合适的位置上。在这篇文章中,我们将介绍如何使用Matlab实现自动泊车。 首先,我们需要了解自动泊车的基本原理。自动泊车系统通常包括车辆、传感器和控制算…...
笔试面试相关记录(4)
(1)实现防火墙的主流技术有哪些? 实施防火墙主要采用哪些技术 - 服务器 - 亿速云 (yisu.com) (2) char arr[][2] {a, b, c, d}; printf("%d", *(arr1)); 输出的是谁的地址?字符c 测试代码如下…...
unity UDP 通信
客户端 接收端 : using System; using System.IO; using System.Collections; using System.Collections.Generic; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using UnityEngine; using UnityEngine.UI;public cla…...
一篇解决JavaScript
华子目录 JavaScript介绍JavaScript的组成JavaScript书写位置内部外部 js注释js输入(prompt)js输出js变量js基本数据类型number(数值类型)string(字符串)Boolean(布尔类型)undefined…...
Unity UGUI(一)基础组件
文章目录 1.Text:文本框2.Image:精灵图3.RawImage:生图4.Button:按钮5.InputField:输入框6.Tooggle:选择框7.Slider:滑动条8.Dropdown:下拉菜单9.Scrollbar:滚动条10.Scr…...
【微服务】六. Nacos配置管理
6.1 Nacos实现配置管理 配置更改热更新 在nacos左侧新建配置管理 Data ID:就是配置文件名称 一般命名规则:服务名称-环境名称.yaml 配置内容填写:需要热更新需求的配置 配置文件的id:[服务名称]-[profile].[后缀名] 分组&#…...
【华为云云耀云服务器L实例评测|云原生】自定制轻量化表单Docker快速部署云耀云服务器
🤵♂️ 个人主页: AI_magician 📡主页地址: 作者简介:CSDN内容合伙人,全栈领域优质创作者。 👨💻景愿:旨在于能和更多的热爱计算机的伙伴一起成长!!&…...
无涯教程-JavaScript - ACOTH函数
描述 ACOTH函数返回数字的反双曲余切。 语法 ACOTH (number)争论 Argument描述Required/OptionalNumberThe absolute value of Number must be greater than 1. i.e., Number must be must be less than -1 or greater than 1.Required Notes 用于计算双曲反余切的方程为-…...
Qt QTreeWidge解决setItemWidget后,导致复选框失效
一、问题: QTreeWidget某一项加上itemWidget后,导致复选框失效问题 二、解决方法 将要加上的widget控件加到该项的后续的列,即控件跟复选框不同一列 三、具体代码 QTreeWidget* treeW new QTreeWidget; treeW->setColumnCount(2); /…...
strncpy
strncpy: 函数介绍: 函数原型: char *strncpy(char *dest, const char *src, int n) 返回值:dest字符串起始地址 说明: 1、当src字符串长度小于n时,则拷贝完字符串后,剩余部分将用空字节填…...
c++学习【23】matlab实现FOC算法
% 创建Figure窗口和滑块 figure;Id_slider uicontrol(Style, slider, Position, [100 50 120 20], ...Min, -5, Max, 5, Value, 1.5, Callback, updateVoltage); Id_text uicontrol(Style, text, Position, [100 80 120 20], String, d轴电流: 1.5);Iq_slider uicontrol(Sty…...
大连网站排名优化价格/网上教育培训机构哪家好
包括像我这样的初学者的文件操作在内的完整步骤假设您有一个.jsonl文件,如:{"reviewerID": "A2IBPI20UZIR0U", "asin": "1384719342", "reviewerName": "cassandra tu \"Yeah, well, thats…...
驻马店市住房和城乡建设局网站首页/北京seo服务销售
D3.js Canvas 绘制组织结构图 使用 D3.js 默认的 svg 渲染 D3默认的树状图画图使用的是svg, 比如这个来自D3作者的例子: https://bl.ocks.org/mbostock/... 使用svg有好有坏: 好处是方便操作dom元素, 添加用户交互坏处是渲染效率不高, 在数据量较大时页面易掉帧, 卡顿在大多数…...
wordpress统计插件下载/网络营销主要有哪些特点
智慧树知到_大数据可视化_2020章节测试答案更多相关问题(103)5______.计算:(-3)332______.计算:(-3)332______.若m为正整数,且a-1,则-(࿰…...
科学新概念seo外链/seo搜索引擎优化业务
什么是构造方法 在创建类时, 可手动添加一个 __init__() 方法,称为构造方法,这是一个实例方法构造方法用于创建实例对象时使用,每当创建一个类的实例对象时,Python 解释器都会自动调用它一般用来初始化对象的某些属性…...
什么网站做代购/长春网站建设技术支持
数据科学家 David Robinson 称,Python 是访问量增长最快的主流编程语言。在 Stackoverflow 上,主流编程语言如 Java、Javascript、C#、php 和 C 的问题访问量过去几年基本没太大的变动,只有 Python 一路呈上升趋势。小学一年级辅导 https://m…...
期货贵金属网站源码建设/如何介绍自己设计的网页
1、用预编译指令符可以避免在多文件工程中调用文件的时候可能出现的重复定义的现象。比如:Main.cpp#include “Animal.h”#include “Fish.h”……Animal.hclass Animal(){}Fish.h#include “Animal.h”class Fish():public Animal{}因此在调用Main.cpp的时候先运行…...