RT-Thread系列10——ETH网口设备

news2024/11/25 9:58:30

文章目录

  • 1. ETH测试
    • 第一步:cubemx配置。
    • 第二步:board.h配置。
    • 第三步:rtthread settings配置
    • 第四步:以太网复位引脚设置
    • 第五步:修改rtthread源码
    • 第六步:修改 cubemx 生成的 main 函数
    • 第七步:编译运行。
    • 第七步:通信测试
  • 2. UDP/TCP通信测试
    • 2.1 UDP测试
      • 2.1.1 UPD 服务端测试
      • 2.1.2 UPD 客户端测试
    • 2.2 TCP通信测试
      • 2.1.2 TCP 客户端测试
      • 2.2.2 TCP 服务端测试

====>>> 文章汇总(有代码汇总) <<<====

目标:使用网口和电脑通信。

  • RT-Thread studio,版本: 2.2.6,不一样其实区别也不大
  • RT-Thread:标准版,4.0.3版本
  • 芯片包版本:0.1.9
  • 开发板:自己做的,主控STM32F407VET6。
  • 网口芯片:太网口LAN8720A
  • cubemx版本:6.8.1

cubemx版本不一样的话,网口的配置过程也不大一样。我现在用的麻烦一点。老版本的cubemx相对简单。

Finsh组件是创建工程后就默认开启的,无需任何配置。

1. ETH测试

新建工程,选择自己的芯片和调试接口即可。

第一步:cubemx配置。

首先配置时钟,一般都拉满。
在这里插入图片描述
勾选上调试的串口、网口。参数默认。

在这里插入图片描述

我这里调试用的串口2,一般都是串口1,根据自己的选择即可。
网口也要根据自己的板子的引脚调整。

生成代码后,关闭cubemx,直接编译,一堆报错,基本都在cubemx下面的main函数里面。

第二步:board.h配置。

在这里插入图片描述

第三步:rtthread settings配置

勾选以太网驱动。
在这里插入图片描述
勾选网络层驱动。
在这里插入图片描述
设置板子 IP 信息
在这里插入图片描述

勾选之后,保存 关闭。

第四步:以太网复位引脚设置

在这里插入图片描述

这里根据自己的板卡引脚修改。

第五步:修改rtthread源码

修改 eth_demo\rt-thread\components\drivers\include\drivers\phy.h文件,注释掉32行。图中 drivers 文件夹下的 drv_eth.c 报错是因为这个变量重定义了。
在这里插入图片描述

第六步:修改 cubemx 生成的 main 函数

在这里插入图片描述

注意,把下面的函数体 也删掉。

此时编译,应该是没有报错能通过的。cubemx中的main函数会用到我们删掉的那两个函数,所有会有警告,不想看可以在main函数中也注释或者删掉。

第七步:编译运行。

调试串口输入 ifconfig 就可以看到板子的ip信息了。
在这里插入图片描述

第七步:通信测试

第一步:把板子的网口和电脑的网口使用网线连接起来。

第二步:把电脑端 ip 更改为和板卡在同一个网段下。

更改本地电脑ip方法,自己百度一下。

在这里插入图片描述

第三步:打开电脑端 cmd 窗口,使用ping命令测试,可以ping通。
在这里插入图片描述
第四步:在串口调试助手中使用 ping命令测试,也可以ping通电脑。

如果不通,关掉电脑防火墙即可。

2. UDP/TCP通信测试

在上面的步骤都能通过以后,进行UDP/TCP通信测试。

2.1 UDP测试

在工程中新建一个 c 文件,添加如下代码。位置根据自己需要放。

/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2023-10-24     Haozi       the first version
 */
#include <rtthread.h>
#include <sys/socket.h> /* 使用BSD socket,需要包含socket.h头文件 */
#include <netdb.h>
#include <string.h>
#include <finsh.h>


/* UDP服务器参数 */
#define BUFSZ                   1024        //接收缓存大小
#define BOARD_SERVER_PORT       5000        //板卡作为服务器的端口号

/* UDP客户端参数 */
#define BOARD_UDP_CLIENT_PORT     20000               //板卡作为客户端端口号
#define UPPER_UDP_SERVER_IP       "192.168.1.125"     //要连接的服务器ip

/*
 * udp 服务端线程,一直等待接收其他udp客户端发来的消息。
 * 本机ip:192.168.1.30
 * 使用的端口号:5000
*/
void udp_server(void *para)
{
    int sock;
    int bytes_read;
    char *recv_data;
    socklen_t addr_len;
    struct sockaddr_in server_addr, client_addr;

    /* 分配接收用的数据缓冲 */
    recv_data = rt_malloc(BUFSZ);
    if (recv_data == RT_NULL)
    {
        /* 分配内存失败,返回 */
        rt_kprintf("No memory\n");
        return;
    }

    /* 创建一个socket,类型是SOCK_DGRAM,UDP类型 */
    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
    {
        rt_kprintf("Socket error\n");

        /* 释放接收用的数据缓冲 */
        rt_free(recv_data);
        return;
    }

    /* 初始化服务端地址 */
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(BOARD_SERVER_PORT);
    server_addr.sin_addr.s_addr = INADDR_ANY;
    rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));

    /* 绑定socket到服务端地址 */
    if (bind(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1)
    {
        /* 绑定地址失败 */
        rt_kprintf("Bind error\n");

        /* 释放接收用的数据缓冲 */
        rt_free(recv_data);
        return;
    }

    addr_len = sizeof(struct sockaddr);
    rt_kprintf("UDPServer Waiting for client on port 5000...\n");

    while (1)
    {
        /* 从sock中收取最大BUFSZ - 1字节数据 */
        bytes_read = recvfrom(sock, recv_data, BUFSZ - 1, 0, (struct sockaddr *)&client_addr, &addr_len);
        /* UDP不同于TCP,它基本不会出现收取的数据失败的情况,除非设置了超时等待 */

        recv_data[bytes_read] = '\0'; /* 把末端清零 */

        /* 输出接收的数据 */
        rt_kprintf("\n(%s , %d) said : ", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
        rt_kprintf("%s", recv_data);

        /* 如果接收数据是exit,退出 */
        if (strcmp(recv_data, "exit") == 0)
        {
            closesocket(sock);

            /* 释放接收用的数据缓冲 */
            rt_free(recv_data);
            break;
        }
    }

    return;
}
MSH_CMD_EXPORT(udp_server, udp server);

/*
 * udp 客户端,每隔2s就往上位机发送当前系统时钟的计数值。
 * 本机ip:192.168.1.30
 * 使用的端口号:20000
*/
static const char send_data[] = "This is UDP Client from RT-Thread.\n"; /* 发送用到的数据 */

void udp_client(void *para)
{
    int sock;
    struct hostent *host;
    struct sockaddr_in server_addr;

    /* 获得host地址(如果是域名,会做域名解析) */
    host = (struct hostent *) gethostbyname(UPPER_UDP_SERVER_IP);

    /* 创建一个socket,类型是SOCK_DGRAM,UDP类型 */
    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
    {
        rt_kprintf("Socket error\n");
        return;
    }

    /* 初始化预连接的服务端地址 */
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(BOARD_UDP_CLIENT_PORT);
    server_addr.sin_addr = *((struct in_addr *)host->h_addr);
    rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));

    /* 总计发送count次数据 */
    while (1)
    {
        /* 发送数据到服务远端 */
        sendto(sock, send_data, strlen(send_data), 0, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));

        /* 线程休眠一段时间 */
        rt_thread_delay(2000);
    }

    /* 关闭这个socket */
    closesocket(sock);
}

MSH_CMD_EXPORT(udp_client, udp client);

2.1.1 UPD 服务端测试

  1. 在串口调试助手中启动udp_server任务。
  2. 打开,网络调试助手。ip设置如下,然后点击连接。
  3. 在网络调试助手输入框输入消息并点击发送,串口会打印出板卡收到的消息。

在这里插入图片描述

电脑信息:端口是任意的,能连接即可。
板卡信息:端口是固定的,在上面板卡程序里面可以改。

2.1.2 UPD 客户端测试

  1. 打开,网络调试助手。ip设置如下。
  2. 重启板卡,在串口调试助手中启动 udp_client任务。
  3. 网络调试助手会受到板卡每2s发送过来的一次数据。

在这里插入图片描述

电脑信息:端口是固定的,在上面板卡程序里面可以改。
板卡信息:随便填吧,没用其实。

2.2 TCP通信测试

在工程中新建一个 c 文件,添加如下代码。位置根据自己需要放。

/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2023-10-24     Haozi       the first version
 */
#include <rtthread.h>
#include <sys/socket.h> /* 使用BSD socket,需要包含socket.h头文件 */
#include <netdb.h>
#include <string.h>
#include <finsh.h>
#include <sys/errno.h>

#define BUFSZ       (1024)
static const char send_data[] = "This is TCP Server from RT-Thread."; /* 发送用到的数据 */

/*
* 程序清单:tcp 服务端
 *
 * 这是一个 tcp 服务端的例程
 * 导出 tcpserv 命令到控制终端
 * 命令调用格式:tcpserv
 * 无参数
 * 程序功能:作为一个服务端,接收并显示客户端发来的数据 ,接收到 exit 退出程序
*/
void tcp_server(int argc, char **argv)
{
    char *recv_data; /* 用于接收的指针,后面会做一次动态分配以请求可用内存 */
    socklen_t sin_size;
    int sock, connected, bytes_received;
    struct sockaddr_in server_addr, client_addr;
    rt_bool_t stop = RT_FALSE; /* 停止标志 */
    int ret;

    recv_data = rt_malloc(BUFSZ + 1); /* 分配接收用的数据缓冲 */
    if (recv_data == RT_NULL)
    {
        rt_kprintf("No memory\n");
        return;
    }

    /* 一个socket在使用前,需要预先创建出来,指定SOCK_STREAM为TCP的socket */
    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    {
        /* 创建失败的错误处理 */
        rt_kprintf("Socket error\n");

        /* 释放已分配的接收缓冲 */
        rt_free(recv_data);
        return;
    }

    /* 初始化服务端地址 */
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(20000); /* 服务端工作的端口 */
    server_addr.sin_addr.s_addr = INADDR_ANY;
    rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));

    /* 绑定socket到服务端地址 */
    if (bind(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1)
    {
        /* 绑定失败 */
        rt_kprintf("Unable to bind\n");

        /* 释放已分配的接收缓冲 */
        rt_free(recv_data);
        return;
    }

    /* 在socket上进行监听 */
    if (listen(sock, 5) == -1)
    {
        rt_kprintf("Listen error\n");

        /* release recv buffer */
        rt_free(recv_data);
        return;
    }

    rt_kprintf("\nTCPServer Waiting for client on port 5000...\n");
    while (stop != RT_TRUE)
    {
        sin_size = sizeof(struct sockaddr_in);

        /* 接受一个客户端连接socket的请求,这个函数调用是阻塞式的 */
        connected = accept(sock, (struct sockaddr *)&client_addr, &sin_size);
        /* 返回的是连接成功的socket */
        if (connected < 0)
        {
            rt_kprintf("accept connection failed! errno = %d\n", errno);
            continue;
        }

        /* 接受返回的client_addr指向了客户端的地址信息 */
        rt_kprintf("I got a connection from (%s , %d)\n",
                   inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));

        /* 客户端连接的处理 */
        while (1)
        {
            /* 发送数据到connected socket */
            ret = send(connected, send_data, strlen(send_data), 0);
            if (ret < 0)
            {
                /* 发送失败,关闭这个连接 */
                closesocket(connected);
                rt_kprintf("\nsend error,close the socket.\r\n");
                break;
            }
            else if (ret == 0)
            {
                /* 打印send函数返回值为0的警告信息 */
                rt_kprintf("\n Send warning,send function return 0.\r\n");
            }

            /* 从connected socket中接收数据,接收buffer是1024大小,但并不一定能够收到1024大小的数据 */
            bytes_received = recv(connected, recv_data, BUFSZ, 0);
            if (bytes_received < 0)
            {
                /* 接收失败,关闭这个connected socket */
                closesocket(connected);
                break;
            }
            else if (bytes_received == 0)
            {
                /* 打印recv函数返回值为0的警告信息 */
                rt_kprintf("\nReceived warning,recv function return 0.\r\n");
                closesocket(connected);
                break;
            }

            /* 有接收到数据,把末端清零 */
            recv_data[bytes_received] = '\0';
            if (strcmp(recv_data, "q") == 0 || strcmp(recv_data, "Q") == 0)
            {
                /* 如果是首字母是q或Q,关闭这个连接 */
                closesocket(connected);
                break;
            }
            else if (strcmp(recv_data, "exit") == 0)
            {
                /* 如果接收的是exit,则关闭整个服务端 */
                closesocket(connected);
                stop = RT_TRUE;
                break;
            }
            else
            {
                /* 在控制终端显示收到的数据 */
                rt_kprintf("RECEIVED DATA = %s \n", recv_data);
            }
        }
    }

    /* 退出服务 */
    closesocket(sock);

    /* 释放接收缓冲 */
    rt_free(recv_data);

    return ;
}
MSH_CMD_EXPORT(tcp_server, tcp server);



/*
 * 程序清单:tcp 客户端
 *
 * 这是一个 tcp 客户端的例程
 * 导出 tcp_client 命令到控制终端
 * 命令调用格式:tcp_client URL PORT
 * URL:服务器地址 PORT::端口号
 * 程序功能:接收并显示从服务端发送过来的信息,接收到开头是 'q' 或 'Q' 的信息退出程序
*/
void tcp_client(int argc, char **argv)
{
    int ret;
    char *recv_data;
    struct hostent *host;
    int sock, bytes_received;
    struct sockaddr_in server_addr;
    const char *url;
    int port;

    if (argc < 3)
    {
        rt_kprintf("Usage: tcp_client URL PORT\n");
        rt_kprintf("Like: tcp_client 192.168.1.125 20000\n");
        return ;
    }

    url = argv[1];
    port = strtoul(argv[2], 0, 10);

    /* 通过函数入口参数url获得host地址(如果是域名,会做域名解析) */
    host = gethostbyname(url);

    /* 分配用于存放接收数据的缓冲 */
    recv_data = rt_malloc(BUFSZ);
    if (recv_data == RT_NULL)
    {
        rt_kprintf("No memory\n");
        return;
    }

    /* 创建一个socket,类型是SOCKET_STREAM,TCP类型 */
    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    {
        /* 创建socket失败 */
        rt_kprintf("Socket error\n");

        /* 释放接收缓冲 */
        rt_free(recv_data);
        return;
    }

    /* 初始化预连接的服务端地址 */
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(port);
    server_addr.sin_addr = *((struct in_addr *)host->h_addr);
    rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));

    /* 连接到服务端 */
    if (connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1)
    {
        /* 连接失败 */
        rt_kprintf("Connect fail!\n");
        closesocket(sock);

        /*释放接收缓冲 */
        rt_free(recv_data);
        return;
    }
    else
    {
        /* 连接成功 */
        rt_kprintf("Connect successful\n");
    }

    while (1)
    {
        /* 从sock连接中接收最大BUFSZ - 1字节数据 */
        bytes_received = recv(sock, recv_data, BUFSZ - 1, 0);
        if (bytes_received < 0)
        {
            /* 接收失败,关闭这个连接 */
            closesocket(sock);
            rt_kprintf("\nreceived error,close the socket.\r\n");

            /* 释放接收缓冲 */
            rt_free(recv_data);
            break;
        }
        else if (bytes_received == 0)
        {
            /* 默认 recv 为阻塞模式,此时收到0认为连接出错,关闭这个连接 */
            closesocket(sock);
            rt_kprintf("\nreceived error,close the socket.\r\n");

            /* 释放接收缓冲 */
            rt_free(recv_data);
            break;
        }

        /* 有接收到数据,把末端清零 */
        recv_data[bytes_received] = '\0';

        if (strncmp(recv_data, "q", 1) == 0 || strncmp(recv_data, "Q", 1) == 0)
        {
            /* 如果是首字母是q或Q,关闭这个连接 */
            closesocket(sock);
            rt_kprintf("\n got a 'q' or 'Q',close the socket.\r\n");

            /* 释放接收缓冲 */
            rt_free(recv_data);
            break;
        }
        else
        {
            /* 在控制终端显示收到的数据 */
            rt_kprintf("\nReceived data = %s ", recv_data);
        }

        /* 发送数据到sock连接 */
        ret = send(sock, send_data, strlen(send_data), 0);
        if (ret < 0)
        {
            /* 接收失败,关闭这个连接 */
            closesocket(sock);
            rt_kprintf("\nsend error,close the socket.\r\n");

            rt_free(recv_data);
            break;
        }
        else if (ret == 0)
        {
            /* 打印send函数返回值为0的警告信息 */
            rt_kprintf("\n Send warning,send function return 0.\r\n");
        }
    }
    return;
}
MSH_CMD_EXPORT(tcp_client, tcp client);

2.1.2 TCP 客户端测试

  1. 网络调试助手设置为 TCP Server模式。并设置地址和端口号。
  2. 在串口调试助手中打开 TCP Client任务。接收电脑服务器发过去的数据。
  3. 在网络调试助手中输入要发送的消息点击发送,串口即可显示接收到的数据。

在这里插入图片描述

2.2.2 TCP 服务端测试

有问题,网络助手连接不上,后续再补。
百度说,把虚拟机的网络禁用就好了,这里测试没行,理由未知。

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

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

相关文章

【MATLAB源码-第76期】基于matlab的OCDM系统在AWGN信道下理论误码率和实际误码率对比仿真。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 正交线性调频分频复用&#xff08;OCDM&#xff0c;Orthogonal Chirp Division Multiplexing&#xff09;是一种无线通信技术&#xff0c;它基于啁啾信号的原理。啁啾信号是一种频率随时间变化的信号&#xff0c;通常频率是线…

Ant Design Vue Select下拉框内容显示不全问题解决

默认情况下&#xff0c;当下拉框的内容长度过长时&#xff0c;会被折叠&#xff0c;这比较影响用户体验&#xff0c;查了下文档&#xff0c;看到有一个属性可以解决这个问题&#xff1a; 没设置的下拉效果&#xff1a; 设置完之后&#xff1a;dropdownMatchSelectWidth{false}&…

在Qt设计师(Qt Designer )控件面板加入自定义控件

目录 1. 问题的提出 2. 本次开发环境说明 3. 具体实现 4. 注意的问题 5. 参考链接 1. 问题的提出 在Qt开发中&#xff0c;经常利用Qt设计师&#xff08;Qt Designer &#xff09;把界面设计好&#xff0c;将界面放到ui文件中&#xff0c;将逻辑处理放到cpp文件中&#xff…

记录第一次利用CVE-2023-33246漏洞实现RocketMQ宿主机远程代码执行的兴奋

我依然记得自己第一次发现xss漏洞时候的兴奋: 我也记得自己第一次发现sql输入时候的快乐: 直到最近我终于收获了人生的第一个远程代码执行漏洞的利用&#xff08;RCE:remote code execute&#xff09;&#xff0c;虽然这个漏洞的危害远超过了前两个&#xff0c;但是快乐不如前…

基于非对称纳什谈判的多微网电能共享运行优化策略(附带MATLAB程序)

基于非对称纳什谈判的多微网电能共享运行优化策略MATLAB程序 参考文献&#xff1a; 《基于非对称纳什谈判的多微网电能共享运行优化策略》——吴锦领 资源地址&#xff1a; 基于非对称纳什谈判的多微网电能共享运行优化策略MATLAB程序 MATLAB代码&#xff1a;基于非对称纳什…

微信小程序:tabbar、事件绑定、数据绑定、模块化、模板语法、尺寸单位

目录 1. tabbar 1.1 什么是tabbar 1.2 配置tabbar 2. 事件绑定 2.1 准备表单 2.2 事件绑定 2.3 冒泡事件及非冒泡事件 3. 数据绑定 3.1 官方文档 4. 关于模块化 5. 模板语法 6. 尺寸单位 1. tabbar 1.1 什么是tabbar 下图中标记出来的部分即为tabbar&#xff1a…

2023年华为杯数学建模E题——代码复盘(第一问)

2023年华为杯数学建模E题 代码复盘 写在最前面目录问题1a计算时间间隔思路说明代码输出结果 插值求解思路代码输出结果 绘图绘制3D图&#xff08;待修改&#xff09; 问题1b数据预处理思路代码 模型训练思路代码输出结果网格调参代码输出结果 写在最前面 超开心又有点遗憾 结果…

matlab二维曲面散点图插值方法

在 MATLAB 中&#xff0c;你可以使用以下函数进行二维曲面散点插值&#xff1a; griddata: 该函数可以在散点数据上进行二维插值&#xff0c;生成平滑的曲面。它支持多种插值方法&#xff0c;包括三次样条插值、最近邻插值、线性插值和自然邻近法插值。 scatteredInterpolant:…

《RT-DETR魔术师》专栏介绍 CSDN独家改进创新实战 专栏目录

RT-DETR魔术师专栏介绍&#xff1a; https://blog.csdn.net/m0_63774211/category_12497375.html ✨✨✨魔改创新RT-DETR &#x1f680;&#x1f680;&#x1f680;引入前沿顶会创新&#xff08;CVPR2023&#xff0c;ICCV2023等&#xff09;&#xff0c;助力RT-DETR &#…

专题知识点-二叉树-(非常有意义的一篇文章)

这里写目录标题 二叉树的基础知识知识点一(二叉树性质 )树与二叉树的相互转换二叉树的遍历层次优先遍历树的深度和广度优先遍历中序线索二叉树二叉树相关遍历代码顺序存储和链式存储二叉树的遍历二叉树的相关例题左右两边表达式求值求树的深度找数找第k个数二叉树非递归遍历代码…

微信小程序 生命周期方法 页面路由 开发示例 自定义全局数据 链接跳转

目录 1. 生命周期方法 2. 页面路由 3. 开发示例 3.1 自定义全局数据 3.2 链接跳转 1. 生命周期方法 打开app.js Page生命周期函数 下面的Page生命周期图与上面的Page生命周期函数进行对比便于理解&#xff1a; 视图线程和应用服务线程会同时运行&#xff0c;应用服务线程…

微信个人号api接口开发

请求URL&#xff1a; http://域名地址/sendFile 请求方式&#xff1a; POST 请求头Headers&#xff1a; Content-Type&#xff1a;application/jsonAuthorization&#xff1a;login接口返回 参数&#xff1a; 参数名必选类型说明wId是string登录实例标识wcId是string接收…

【保姆级教程】Linux安装JDK8

本文以centos7为例&#xff0c;一步一步进行jdk1.8的安装。 1. 下载安装 官网下载链接&#xff1a; https://www.oracle.com/cn/java/technologies/downloads/#java8 上传jdk的压缩包到服务器的/usr/local目录下 在当前目录解压jdk压缩包&#xff0c;如果是其它版本&#xf…

Nessus漏洞扫描工具

Nessus 1、官网下载安装包2、centos7 安装Nessus3、启动Nessus4、网页访问88435、离线激活工具6、其他问题7、漏洞扫描使用 Nessus 是全世界最多人使用的系统漏洞扫描与分析软件。总共有超过75,000个机构使用Nessus 作为扫描该机构电脑系统的软件。 1、官网下载安装包 官网下载…

【Linux】Ubuntu16.04下完美安装python高版本及对应版本的pip

Ubuntu16.04下完美安装python高版本及对应版本的pip 方法一:直接用命令安装python3.6&#xff08;但我没安装成功&#xff09; 好像是因为Ubuntu16.04的软件仓库&#xff08;源&#xff09;中python的最高版本就是python3.5&#xff0c;所以无法直接用apt来安装 #方法一 sudo…

【开源】基于Vue.js的校园失物招领管理系统的设计和实现

目录 一、摘要1.1 项目介绍1.2 项目详细录屏 二、研究内容2.1 招领管理模块2.2 寻物管理模块2.3 系统公告模块2.4 感谢留言模块 三、界面展示3.1 登录注册3.2 招领模块3.3 寻物模块3.4 公告模块3.5 感谢留言模块3.6 系统基础模块 四、免责说明 一、摘要 1.1 项目介绍 基于Vue…

【软考篇】中级软件设计师 第二部分(一)

中级软件设计师 第二部分&#xff08;一&#xff09; 八. 层次化结构8.1 局部性原理8.2 体系8.3 分类8.3.1 存取方式8.3.2 工作方式 8.4 Cache8.4.1 例题 8.5 地址映像 九. 主存编址9.1 例题一 十. 可靠性10.1 串联系统和并联系统 十一. 网络安全11.1 保密性11.2 完整性&#x…

金财数科无代码开发平台:轻松实现电商、CRM、广告推广系统的集成连接

连接与集成&#xff1a;挖掘电商平台的潜力 金财数科是一家领先的信息技术公司&#xff0c;专注于利用前沿技术如互联网、人工智能、大数据和区块链等&#xff0c;为传统财税信息化方案和产品提供升级改造&#xff0c;并打造新一代智能财税SaaS平台。我们的目标是帮助企业通过…

Python接口测试框架选择之pytest+yaml+Allure!

一、为什么选择pytest&#xff1f; pytest完全兼容python自带的unittest pytest让单元测试更简单&#xff0c;能很好的管理测试用例。 对于实现接口测试的复杂场景&#xff0c;pytest的fixture、PDB等高阶用法都能实现需求。 入门简单&#xff0c;对于代码基础薄弱的团队人…

UWB基础——IEEE 802.15.4z中可选波形

在前面的文章&#xff1a;UWB基础——基带简介中介绍了关于UWB基带脉冲波形以及相关的定义&#xff0c;本文继续介绍在IEEE 802.15.4z-2020标准中新增的一些兼容脉冲形状。 1. 基带脉冲响应 传输脉冲形状p(t)受到与标准参考脉冲r(t)的互相关函数形状的限制。 两个脉冲之间归一…