[嵌入式系统-24]:RT-Thread -11- 内核组件编程接口 - 网络组件 - TCP/UDP Socket编程

news2025/3/11 0:11:46

目录

一、RT-Thread网络组件

1.1 概述

1.2 RT-Thread支持的网络协议栈

1.3 RT-Thread如何选择不同的网络协议栈

二、Socket编程

2.1 概述

2.2 UDP socket编程

2.3 TCP socket编程

2.4 TCP socket收发数据


一、RT-Thread网络组件

1.1 概述

RT-Thread 是一个开源的嵌入式实时操作系统(RTOS),它提供了丰富的网络组件用于网络通信。

RT-Thread 的网络组件包括以下几个方面:

  1. TCP/IP 协议栈:RT-Thread 提供了完整的 TCP/IP 协议栈,包括 IP 协议、TCP 协议和 UDP 协议等。它支持 IPV4 和 IPV6,并提供了常用的网络协议(如 DHCP、DNS)的实现。

  2. Socket API:RT-Thread 提供了类似于 POSIX socket API 的接口,使开发者可以使用常见的网络编程模型(如 TCP 或 UDP)在 RT-Thread 上进行网络通信。

  3. LWIP:RT-Thread 基于 LWIP(Lightweight IP)实现了 TCP/IP 协议栈。LWIP 是一个轻量级的 TCP/IP 协议栈,具有较小的内存占用和代码体积,适合嵌入式系统。

  4. PPP:RT-Thread 提供了 PPP(Point-to-Point Protocol)的实现,支持通过串口或以太网设备建立拨号连接,并通过拨号方式实现网络通信。

  5. 协议支持:除了 TCP/IP 协议栈外,RT-Thread 还支持其他网络协议,如 MQTT、CoAP、WebSocket 等,使开发者可以方便地实现各种应用场景的网络通信功能。

总的来说,RT-Thread 的网络组件提供了完整的网络通信功能,并提供了开发者常用的网络编程接口和协议支持,使嵌入式设备可以便捷地实现各种网络应用。

1.2 RT-Thread支持的网络协议栈

RT-Thread 支持多种网络协议栈,常见的有如下几种:

  1. LwIP(Lightweight IP)LwIP 是一个轻量级的网络协议栈,专为嵌入式系统设计,具有小巧、高效的特点。RT-Thread 使用 LwIP 作为默认的网络协议栈,支持 IPv4、IPv6、TCP、UDP、ICMP 等协议。

  2. uIP:uIP 也是一个轻量级的网络协议栈,适用于资源受限的嵌入式系统。RT-Thread 也提供了对 uIP 的支持,使得开发者可以根据实际需求选择合适的网络协议栈。

  3. Salstack:RT-Thread 也提供了 Salstack(Simple Abstract Layer for Stack)协议栈,相对于 LwIP 和 uIP 更轻量级。Salstack 的设计目标是提供简单易用的网络功能,支持 TCP、UDP、ICMP、ARP 等常用协议。

  4. MiCO TCP/IP:MiCO 是一种基于 LwIP 的 TCP/IP 协议栈,适用于连接性和通信性能要求较高的应用场景。RT-Thread 也支持 MiCO TCP/IP 协议栈。

这些网络协议栈在 RT-Thread 中提供了丰富的网络功能,开发者可以根据项目需求选择合适的协议栈。同时,RT-Thread 也支持用户自定义网络协议栈,使得定制化网络功能变得更加灵活。在使用网络功能时,你可以根据具体情况选择合适的网络协议栈,并结合相应的文档和示例进行开发。

1.3 RT-Thread如何选择不同的网络协议栈

在 RT-Thread 中选择不同的网络协议栈通常需要根据具体的项目需求和硬件平台来进行配置和选择。下面是一般的步骤:

  1. 配置网络协议栈

    • 进入 RT-Thread 的 BSP 配置目录,在 rtconfig.h 或 menuconfig 工具中找到网络协议栈的配置选项。
    • 根据需要选择要使用的网络协议栈,比如 LwIP、uIP、Salstack 或其他协议栈。
    • 根据选择的网络协议栈,进行相应的配置,比如 IP 地址、子网掩码、网关等。
  2. 初始化网络协议栈

    • 在应用程序中调用相应的网络协议栈初始化函数,以初始化选择的协议栈。具体的初始化函数根据选择的协议栈而定,一般在启动代码或应用程序初始化阶段执行。
  3. 编写网络通信代码

    • 根据选择的网络协议栈,编写相应的网络通信代码,比如创建套接字、发送数据、接收数据等操作。
    • 根据选定的协议栈提供的 API,实现对网络功能的调用和控制。
  4. 调试和测试

    • 在选择和配置完成后,进行调试和测试,确保网络协议栈正常工作,网络连接稳定可靠。
    • 可以使用网络调试工具或者监视网络数据流量等方法来验证网络功能是否符合预期。

通过以上步骤,你可以在 RT-Thread 中灵活选择并配置不同的网络协议栈,以满足项目的需求。在选择和配置的过程中,建议参考 RT-Thread 的官方文档和示例代码,以便更好地理解和使用不同的网络协议栈功能。

二、Socket编程

2.1 概述

在 RT-Thread 中进行 socket 编程是一种常见的网络编程方式,可以通过套接字(socket)接口实现网络通信。以下是关于 RT-Thread 中 socket 编程的概述:

  1. 套接字(Socket)

    • 在 RT-Thread 中,套接字是一种抽象的通信端点,通过套接字可以进行网络通信。开发者可以通过套接字接口进行数据的发送和接收,实现网络应用程序的通信功能。
  2. Socket 接口

    • RT-Thread 提供了类似于 POSIX 标准的 socket 接口,开发者可以直接调用这些接口实现网络通信,如创建套接字、绑定地址、监听连接、发送数据、接收数据等操作。
  3. 常用函数

    • 在 RT-Thread 中,常用的 socket 函数包括 socket()bind()listen()accept()connect()send()recv() 等,这些函数可以实现套接字的创建、绑定、监听、连接以及数据的发送和接收。
  4. 网络通信模式

    • RT-Thread 中的 socket 编程支持常见的网络通信模式,包括 TCP 和 UDP。开发者可以根据需要选择合适的协议来实现可靠的数据传输(TCP)或者快速的数据传输(UDP)。
  5. 多线程环境

    • RT-Thread 是一个支持多线程的实时操作系统,因此在进行 socket 编程时,需要考虑多线程环境下的并发和同步。开发者可以使用 RT-Thread 提供的线程同步机制来保护共享资源,确保多线程间的数据安全性。
  6. 错误处理

    • 在 socket 编程中,需要及时处理异常情况和错误,比如网络连接失败、数据传输超时等。通过对错误码进行检查和处理,可以提高程序的健壮性和稳定性。

通过使用 socket 接口,开发者可以在 RT-Thread 中实现各种网络应用程序,如客户端和服务器程序、网络数据采集和处理等。在进行 socket 编程时,建议结合 RT-Thread 提供的文档和示例代码,加深对网络通信的理解,并根据具体需求灵活应用各种 socket 函数。

2.2 UDP socket编程

在 RT-Thread 中进行 UDP(用户数据报协议) socket 编程是一种常见的网络编程方式,可以实现基于 UDP 协议的数据通信。以下是在 RT-Thread 中进行 UDP socket 编程的基本步骤:

  1. 创建 UDP 套接字

    • 使用 socket() 函数创建一个 UDP 套接字。在创建套接字时,需要指定协议族为 AF_INET(IPv4 地址族)或 AF_INET6(IPv6 地址族),类型为 SOCK_DGRAM(数据报套接字),协议为 IPPROTO_UDP(UDP 协议)。
  2. 绑定地址

    • 使用 bind() 函数将 UDP 套接字绑定到本地 IP 地址和端口上。通过绑定地址,UDP 套接字可以监听指定的本地地址和端口,以接收发送到该地址的数据包。
  3. 发送数据

    • 使用 sendto() 函数向目标地址发送 UDP 数据包。需要指定目标 IP 地址(目标主机地址)和端口号,以及待发送的数据内容和长度。
  4. 接收数据

    • 使用 recvfrom() 函数从 UDP 套接字接收数据包。可以指定一个缓冲区来存储接收到的数据,同时获取发送方的 IP 地址和端口号。
  5. 关闭套接字

    • 使用 closesocket() 函数关闭 UDP 套接字,释放资源并停止网络通信。

下面是一个简单的示例代码,演示了如何在 RT-Thread 中使用 UDP 套接字发送和接收数据:

#include <rtthread.h>
#include <sys/socket.h>

void udp_socket_demo(void)
{
    int sockfd;
    struct sockaddr_in addr;
    char buffer[128];

    // 创建 UDP 套接字
    sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

    // 绑定本地地址和端口
    addr.sin_family = AF_INET;
    addr.sin_port = htons(12345);
    addr.sin_addr.s_addr = inet_addr("192.168.1.100");
    bind(sockfd, (struct sockaddr *)&addr, sizeof(addr));

    // 发送数据
    sendto(sockfd, "Hello UDP", 9, 0, (struct sockaddr *)&addr, sizeof(addr));

    // 接收数据
    recvfrom(sockfd, buffer, sizeof(buffer), 0, NULL, 0);

    // 关闭套接字
    closesocket(sockfd);
}

在实际应用中,开发者可以根据具体需求和场景,进行更加复杂和完善的 UDP socket 编程,实现各种基于 UDP 协议的网络通信功能。同时,建议结合 RT-Thread 的网络编程文档和示例,加深对 UDP socket 编程的理解,并进行必要的调试和测试工作。

2.3 TCP socket编程

在 RT-Thread 中进行 TCP socket 编程时,可以同时实现客户端和服务器端的功能。

首先,我们先介绍服务器端的示例代码:

#include <rtthread.h>
#include <netdb.h>
#include <sys/socket.h>

#define PORT 8080

int main(void)
{
    int sockfd, newsockfd;
    struct sockaddr_in server_addr, client_addr;
    socklen_t client_len;
    
    // 创建 TCP socket
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
    {
        rt_kprintf("Failed to create TCP socket\n");
        return -1;
    }
    
    // 设置服务器地址
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = INADDR_ANY;
    server_addr.sin_port = htons(PORT);
    
    // 绑定服务器地址
    if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
    {
        rt_kprintf("Failed to bind address\n");
        return -1;
    }
    
    // 开始监听
    if (listen(sockfd, 5) < 0)
    {
        rt_kprintf("Failed to listen on socket\n");
        return -1;
    }
    
    rt_kprintf("Server listening on port %d\n", PORT);
    
    while (1)
    {
        // 接受客户端连接
        client_len = sizeof(client_addr);
        newsockfd = accept(sockfd, (struct sockaddr *)&client_addr, &client_len);
        if (newsockfd < 0)
        {
            rt_kprintf("Failed to accept client connection\n");
            return -1;
        }
        
        rt_kprintf("Accepted new client connection\n");
        
        // 在这里可以进行与客户端通信的处理
        
        // 处理完client的通信,关闭连接
        close(newsockfd);
    }
    
    return 0;
}

上述代码中,服务器端首先创建一个 TCP socket,并绑定到指定的 IP 地址和端口号。然后通过 listen 函数开始监听客户端的连接请求。在接收到客户端的连接请求后,使用 accept 函数接受连接,创建一个新的 socket 来与客户端进行通信。在这个循环中,服务器端可以与多个客户端进行通信。

接下来是客户端的示例代码:

#include <rtthread.h>
#include <netdb.h>
#include <sys/socket.h>

#define SERVER_IP "192.168.0.100"
#define SERVER_PORT 8080

int main(void)
{
    int sockfd;
    struct sockaddr_in server_addr;
    
    // 创建 TCP socket
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
    {
        rt_kprintf("Failed to create TCP socket\n");
        return -1;
    }
    
    // 设置服务器地址
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(SERVER_PORT);
    server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
    
    // 连接服务器
    if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
    {
        rt_kprintf("Failed to connect to server\n");
        return -1;
    }
    
    // 在这里可以进行与服务器通信的处理
    
    // 关闭连接
    close(sockfd);
    
    return 0;
}

上述代码中,客户端创建一个 TCP socket,并使用 connect 函数连接到指定的服务器地址和端口号。在连接建立后,客户端可以进行与服务器通信的处理。

请注意,上述示例代码中的 IP 地址和端口号需要根据实际情况进行修改。在实际开发中,你可能需要处理更多的错误和异常情况,并且在通信过程中进行数据的发送和接收操作。

另外,还可以通过 RT-Thread 提供的套接字封装库 lwip_socket.h 来简化 TCP socket 编程。可以参考 RT-Thread 官方文档和示例代码获取更详细的信息和使用方法。

2.4 TCP socket收发数据

在 RT-Thread 上进行 TCP socket 编程,你可以使用 RT-Thread 提供的 Socket API 来创建和管理 TCP socket。

对于客户端,你可以按照以下步骤进行编程:

  1. 使用 socket 函数创建一个套接字,指定协议族为 AF_INET,类型为 SOCK_STREAM,以及协议为 IPPROTO_TCP。
  2. 使用 connect 函数将套接字连接到服务器的 IP 地址和端口号。
  3. 使用 send 函数来发送数据到服务器。
  4. 使用 recv 函数来接收服务器发送的数据。
  5. 使用 close 函数关闭套接字。

下面是一个简单的客户端代码示例:

#include <rtthread.h>
#include <netdb.h>
#include <sys/socket.h>

#define SERVER_IP       "192.168.1.100"   // 服务器 IP 地址
#define SERVER_PORT     5000              // 服务器端口号

void client_thread_entry(void* parameter)
{
    int sockfd;
    struct sockaddr_in server_addr;
    char buffer[1024];

    // 创建套接字
    if ((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
    {
        rt_kprintf("Socket creation failed\n");
        return;
    }

    // 设置服务器地址信息
    rt_memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(SERVER_PORT);
    server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);

    // 连接到服务器
    if (connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0)
    {
        rt_kprintf("Connection failed\n");
        close(sockfd);
        return;
    }

    // 发送数据到服务器
    const char* data = "Hello, server!";
    if (send(sockfd, data, strlen(data), 0) < 0)
    {
        rt_kprintf("Sending data failed\n");
        close(sockfd);
        return;
    }

    // 接收服务器发送的数据
    int recv_len;
    if ((recv_len = recv(sockfd, buffer, sizeof(buffer), 0)) > 0)
    {
        buffer[recv_len] = '\0';
        rt_kprintf("Received data from server: %s\n", buffer);
    }
    else
    {
        rt_kprintf("Receiving data failed\n");
    }

    // 关闭套接字
    close(sockfd);
}

// 启动客户端线程
int start_client(void)
{
    rt_thread_t thread;
    thread = rt_thread_create("client", client_thread_entry, RT_NULL, 2048, 25, 10);
    if (thread != RT_NULL)
    {
        rt_thread_startup(thread);
        return 0;
    }
    return -1;
}

对于服务器端,你可以按照以下步骤进行编程:

  1. 使用 socket 函数创建一个套接字,指定协议族为 AF_INET,类型为 SOCK_STREAM,以及协议为 IPPROTO_TCP。
  2. 使用 bind 函数将套接字绑定到服务器的 IP 地址和端口号。
  3. 使用 listen 函数开始监听客户端连接请求。
  4. 使用 accept 函数接受客户端的连接请求,并返回一个新的套接字,通过这个套接字与客户端进行通信。
  5. 使用 send 函数发送数据给客户端。
  6. 使用 recv 函数接收客户端发送的数据。
  7. 使用 close 函数关闭套接字。

下面是一个简单的服务器端代码示例:

#include <rtthread.h>
#include <netdb.h>
#include <sys/socket.h>

#define SERVER_PORT     5000              // 服务器端口号

// 服务器线程的主函数
void server_thread_entry(void* parameter)
{
    int sockfd, new_sockfd;
    struct sockaddr_in server_addr, client_addr;
    socklen_t addr_len = sizeof(client_addr);
    char buffer[1024];

    // 创建套接字
    if ((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
    {
        rt_kprintf("Socket creation failed\n");
        return;
    }

    // 设置服务器地址信息
    rt_memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(SERVER_PORT);
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);

    // 绑定套接字到服务器地址
    if (bind(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0)
    {
        rt_kprintf("Binding failed\n");
        close(sockfd);
        return;
    }

    // 开始监听连接请求
    if (listen(sockfd, 5) < 0)
    {
        rt_kprintf("Listening failed\n");
        close(sockfd);
        return;
    }

    rt_kprintf("Waiting for client connection...\n");

    // 接受客户端的连接请求
    if ((new_sockfd = accept(sockfd, (struct sockaddr*)&client_addr, &addr_len)) < 0)
    {
        rt_kprintf("Accepting failed\n");
        close(sockfd);
        return;
    }

    rt_kprintf("Client connected\n");

    // 接收客户端发送的数据
    int recv_len;
    if ((recv_len = recv(new_sockfd, buffer, sizeof(buffer), 0)) > 0)
    {
        buffer[recv_len] = '\0';
        rt_kprintf("Received data from client: %s\n", buffer);

        // 发送数据给客户端
        const char* data = "Hello, client!";
        if (send(new_sockfd, data, strlen(data), 0) < 0)
        {
            rt_kprintf("Sending data failed\n");
        }
    }
    else
    {
        rt_kprintf("Receiving data failed\n");
    }

    // 关闭套接字
    close(new_sockfd);
    close(sockfd);
}



// 创建并且启动服务器线程
int start_server(void)
{
    rt_thread_t thread;
    thread = rt_thread_create("server", server_thread_entry, RT_NULL, 2048, 25, 10);
    if (thread != RT_NULL)
    {
        rt_thread_startup(thread);
        return 0;
    }
    return -1;
}

你可以根据需要将这两段代码添加到你的 RT-Thread 项目中,并根据实际情况修改服务器的 IP 地址和端口号。代码中的注释可以帮助你理解每个步骤的功能。

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

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

相关文章

微星B85 PCMATE 配合 E3-1230V3锁全核3.7

参考&#xff1a; Non-K超频&#xff0c;i5-12490F 微星 MAG B760M MORTAR MAX WIFI DDR4 超频分享 - 知乎 微星科技 | 微星科技 ring ratio 的说明 英特尔CPU 可以调整的ring ratio (ring 频率&#xff09;是什么&#xff1f; - 知乎 1. 主要调节的是 CPU倍频&#xf…

磁盘删除的文件怎么恢复?4个简单方法(2024更新版)

“我有很多文件都保存在电脑磁盘里了&#xff0c;想问问电脑磁盘删除的文件有什么方法可以快速恢复吗&#xff1f;非常感谢大家&#xff01;” 在日常工作和生活中&#xff0c;我们经常会在磁盘中存储大量的文件。这些文件对我们来说或许都有特殊的意义。磁盘删除的文件怎么恢复…

数据模型概念

一、概念 (1) 定义 在数据库系统中针对不同的使用对象和应用目的&#xff0c;采用不同的数据模型。根据模型的应用的不同目的&#xff0c;可以将这些模型划分为两类&#xff1a; (2) 分类 A&#xff1a;概念数据模型 它也称信息模型它是按用户的观点&#xff08;观念世界&…

GPT-SoVITS-WebUI 克隆声音 macos搭建

强大的少样本语音转换与语音合成Web用户界面 macos运行参考 macos conda create -n GPTSoVits python3.9 conda activate GPTSoVits激活环境 conda activate GPTSoVits停用 conda deactivate mkdir GPTSoVits cd GPTSoVits git clone https://github.com/RVC-Boss/GPT-SoVITS…

C++之内存对齐

目录 内存对齐 一、内存对齐解释 二、为什么要内存对齐&#xff1f; 三、内存对齐的三大规则 3.1、数据成员对齐规则 3.2、结构(或联合)的整体对齐规则 3.3、结构体作为成员 3.4、代码例子 内存对齐 一、内存对齐解释 对齐规则是按照成员的声明顺序&#xff0c;依次安排…

学历太低,可以学这5个技术,不但好找工作,工资也挺高的!

前言 我今年23岁&#xff0c;勉强把高中上完了。 大家都说上高中的时候非常辛苦&#xff0c;但在我看来&#xff0c;却不是这样的。 因为那时候根本就没有&#xff0c;把精力放在学习上面&#xff0c;而是经常出去泡网吧。 没办法&#xff0c;一个班级里面&#xff0c;大多…

2024年【道路运输企业主要负责人】找解析及道路运输企业主要负责人试题及解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年【道路运输企业主要负责人】找解析及道路运输企业主要负责人试题及解析&#xff0c;包含道路运输企业主要负责人找解析答案和解析及道路运输企业主要负责人试题及解析练习。安全生产模拟考试一点通结合国家道路…

【制作100个unity游戏之25】3D背包、库存、制作、快捷栏、存储系统、砍伐树木获取资源、随机战利品宝箱12(附带项目源码)

效果演示 文章目录 效果演示系列目录前言悬停显示物品详情源码完结 系列目录 前言 欢迎来到【制作100个Unity游戏】系列&#xff01;本系列将引导您一步步学习如何使用Unity开发各种类型的游戏。在这第25篇中&#xff0c;我们将探索如何用unity制作一个3D背包、库存、制作、快…

【C++】c++中的函数模板

文章目录 前言什么是函数模板为什么要有模板怎么用函数模板 前言 c语言中没有提供模板&#xff0c;要求实现一个Add函数&#xff0c;对于不同的数据类型可能存在Add_int(),Add_double(&#xff09;等函数&#xff0c;这种重复操作比较的低效&#xff0c;c提供了函数重载的功能…

【感知机】感知机(perceptron)学习算法的对偶形式

感知机( perceptron )是二类分类的线性分类模型&#xff0c;其输入为实例的特征向量&#xff0c;输出为实例的类别&#xff0c;取1 和-1二值。感知机对应输入空间(特征空间)中将实例划分为正负两类的分离超平面&#xff0c;是一种判别模型。感知机是神经网络与支持向量机的基础…

第十二章[模块]:12.5:标准库:zipfile

一,认识zipfile: 1,什么是zipfile? zipfile是python里用来做zip格式编码的压缩和解压缩的, 它采用平时应用非常常见的zip格式, 所以这个模块使用频率也很高 2,官方文档: zipfile --- 使用ZIP存档 — Python 3.12.2 文档源代码: Lib/zipfile/ ZIP 文件格式是一个常用的归…

一款服务于医院临床数据资源建设的平台,助力医疗信息化发展

随着医疗技术的不断发展&#xff0c;医院需要越来越多的临床数据来支持科研、教学和临床实践。然而&#xff0c;在传统的医疗系统中&#xff0c;数据分散、信息割裂、无法有效整合和共享。为了解决这一问题&#xff0c;临床数据资源整合平台应运而生。 临床数据资源整合平台是…

19-k8s的附加组件-coreDNS组件

一、概念 coreDNS组件&#xff1a;就是将svc资源的名称解析成ClusterIP&#xff1b; kubeadm部署的k8s集群自带coreDNS组件&#xff0c;二进制部署需要自己手动部署&#xff1b; [rootk8s231 ~]# kubectl get pods -o wide -A k8s系统中安装了coreDNS组件后&#xff0c;会有一个…

“挖矿”系列:细说Python、conda 和 pip 之间的关系

继续挖矿&#xff0c;挖“金矿”&#xff01; 1. Python、conda 和 pip&#xff08;挖“金矿”工具&#xff09; Python、conda 和 pip 是在现代数据科学和软件开发中常用的工具&#xff0c;它们各自有不同的作用&#xff0c;但相互之间存在密切的关系&#xff1a; Python&…

半理想架构的Doherty功率放大器理论与仿真-基于GAN器件CGH40010F

半理想架构的Doherty功率放大器理论与仿真-基于GAN器件CGH40010F 理想架构的Doherty功率放大器理论与仿真中已经介绍了如何在ADS中使用理想电流源来对DPA的架构进行仿真。但是理想的电流源太理想了&#xff0c;电压、电流的许多行为都是需要自己使用数学公式去严格定义&#x…

RegExp正则表达式左限定右限定左右限定,预查询,预查寻,断言 : (?<= , (?= , (?<! , (?!

RegExp正则表达式左限定右限定左右限定,预查询,预查寻,断言 : (?< , (? , (?<! , (?! 有好多种称呼 (?< , (? , (?<! , (?! 有好多种称呼 , 我称为: 左限定, 右限定, 左否定, 右否定 (?<左限定)    (?右限定)(?<!左否定)    (?!右限定) 再…

直播预告贴纸功能与直播商品预告功能设置基础

一.短视频预告贴纸功能 1.功能介绍 2.使用说明 设置预告贴纸入口 &#xff08;1&#xff09;拍摄视频时添加贴纸 &#xff08;2&#xff09;关播页去发布下一条短视频预告 &#xff08;3&#xff09;主播个人主页–直播动态 3.开播时间设置 4.开播提醒 5.用户端功能展示…

Chrome 关闭F12 网络选项下的大时间段图

把所有的按钮点了一遍&#xff0c;终于找到了 点开F12点右上的小齿轮&#xff0c;把概览取消勾选就可以了 英文的控制台中叫Overview

python-产品篇-游戏-成语填填乐

文章目录 准备代码效果 准备 无需其他文件&#xff0c;复制即用 代码 import random list["春暖花开","十字路口","千军万马","白手起家","张灯结彩","风和日丽","万里长城","人来人往",&…

RocketMQ(三):消息类型(普通、定时、顺序和事务消息)——备份

1 普通消息 普通消息为Apache RocketMQ最基础的消息&#xff0c;区别于有特性的顺序消息、定时/延时消息和事务消息。本节介绍普通消息的应用场景、功能原理、使用方法和使用建议。 1.1 应用场景 普通消息一般应用于微服务解耦、事件驱动、数据集成等场景&#xff0c;这些场景…