鸿蒙Hi3861学习十五-Huawei LiteOS-M(Socket客户端)

news2024/11/24 18:59:11

一、简介

        在网络编程的时候,不管是客户端还是服务端,都离不开Socket。那什么是Socket,这里做个简单介绍。详细的内容,可以参考这篇文章:WIFI学习一(socket介绍)_wifi socket_t_guest的博客-CSDN博客

         socket在计算机领域,被翻译为“套接字”。它是计算机之间进行通信的一种约定一种方式,通过这种方式,一台计算机可以接收或向另外一台计算机收发数据。

        socket是基于“打开open –> 读写write/read –> 关闭close”模式来设计的。socket可以看做是一种特殊的文件,通过一下socket函数来实现打开关闭读/写IO

        socket客户端编程的总体流程可以归结为以下步骤,初始化socket连接服务器(connect)读/写(write/read)关闭(close)

 二、API介绍

      socket

        函数功能:

        创建一个socket描述符,用来唯一标识一个socket。后续需要通过该描述符进行读写操作

        函数原型:

int socket(int domain, int type, int protocol)

        参数:

        domain:IP地址类型。常用的类型有AF_INET(IPV4)、AF_INET6(IPV6)。

        type:数据传输方式/套接字类型。常用的类型有SOCK_STREAM(流格式套接字/面向连接的套接字 TCPSOCK_DGRAM(数据报套接字/无连接的套接字 UDP

        protocol:传输协议。 默认为0,系统自动推演使用的协议。也可以手动输入,常用的协议有,IPPROTO_TCPIPPTOTO_UDP、IPPROTO_SCTP、IPPROTO_TIPC等,它们分别对应TCP传输协议、UDP传输协议、STCP传输协议、TIPC传输协议。type和protocol不可以随意组合,如SOCK_STREAM不可以跟IPPROTO_UDP组合。

        返回值:

        NULL:失败

        其他值:Sockcet描述符

        实例:

int tcp_socket = socket(AF_INET, SOCK_STREAM, 0);  //创建TCP套接字
 
int udp_socket = socket(AF_INET, SOCK_DGRAM, 0);  //创建UDP套接字

      lwip_connect

        函数功能:

        客户端通过该函数与服务端建立连接

        函数原型:

#define lwip_connect      connect
int connect(int fd, const struct sockaddr *addr, socklen_t len)

        参数:

        fd:socket描述符,socket()函数返回

        addr:要连接的服务端相关信息,包括IP和端口等

        len:服务端相关信息的长度

        返回值:

        -1:失败

        0:成功

        实例:

    int sock_fd; 

    struct sockaddr_in socket_addr;
    memset(&socket_addr, 0, sizeof(socket_addr));

    socket_addr.sin_family = AF_INET;	//IPV4
    socket_addr.sin_port = htons(_PROT_);	//端口
    socket_addr.sin_addr.s_addr = inet_addr("192.168.3.198");	//IP地址转换

    socklen_t addr_length = sizeof(socket_addr);

    LOG_I( "connect port:%d, addr:%s",_PROT_,inet_ntoa(socket_addr.sin_addr));

    int ret  = 0;

    ret = lwip_connect(sock_fd, (struct sockaddr *)&socket_addr, addr_length);
    if(ret < 0) //失败{}

         如果网关即为服务端,这里相关信息可以这么写。

struct netif *sta_if = netifapi_netif_find("wlan0"); 
socket_addr.sin_addr.s_addr = inet_addr(ipaddr_ntoa(&sta_if->gw));    //网关IP

      lwip_write

        函数功能:

        向套接字写数据

        函数原型:

ssize_t lwip_write(int s, const void *data, size_t size)

        参数:

        s:socket描述符,socket()函数返回

        data:要发送的数据

        size:要发送数据的长度

        返回值:

        -1:失败

        其他值:成功发送的字节数

        实例:

int sock_fd;
const char *send_data = "This is a socket client test!\r\n";
if(lwip_write(sock_fd,send_data, strlen(send_data)) != -1)    //发送成功
{}

      lwip_read

        函数功能:

        从套接字中读取数据阻塞等待

        函数原型:

ssize_t lwip_read(int s, void *mem, size_t len)

        参数:

        s:socket描述符,socket()函数返回

        mem:接收到的数据存储的地址

        len:最大接收数据长度

        返回值:

        -1:失败

        其他值:成功则返回读取到的字节数,遇到文件结尾则返回0

        实例:

int sock_fd; 
char recvBuf[512] = {0};
if((temp_len = lwip_read(sock_fd, recvBuf, sizeof(recvBuf))) > 0) //读成功
{}

      lwip_close

        函数功能:

        关闭之前打开的套接字

        函数原型:

int closesocket(int s)

        参数:

        s:socket描述符,socket()函数返回

        返回值:

        0:成功

        其他值:失败

        实例:

int sock_fd; 
closesocket(sock_fd);

      sendto

        函数功能:

        发送数据到服务器端(一般用于UDP)。

        函数原型:

ssize_t sendto(int fd, const void *buf, size_t len, int flags, const struct sockaddr *addr, socklen_t alen)

        参数:

        fd:socket描述符,socket()的返回值。

        buf:要发送的数据

        len:要发送数据的长度

        flags:默认0

        addr:服务端相关信息。

        alen:服务端信息长度

        返回值:

        -1:失败

        其他值:成功发送的字节数

        实例:

int sock_fd;

//服务器的地址信息
struct sockaddr_in send_addr;
socklen_t addr_length = sizeof(send_addr);

//初始化预连接的服务端地址
send_addr.sin_family = AF_INET;
send_addr.sin_port = htons(_PROT_);
send_addr.sin_addr.s_addr = inet_addr("192.168.3.198");
addr_length = sizeof(send_addr);
sendto(sock_fd, send_data, strlen(send_data), 0, (struct sockaddr *)&send_addr, addr_length);

      recvfrom

        函数功能:

        接收socket传输过来的数据(一般用于UDP),阻塞等待

        函数原型:

ssize_t recvfrom(int s, void *mem, size_t len, int flags,
                 struct sockaddr *from, socklen_t *fromlen)

        参数:

        s:socket描述符,socket()函数返回

        mem:接收到的数据存放的地址

        len:最大接收数据长度、

        flags:默认为0。

        addr:服务端相关信息。

        alen:服务端信息长度

        返回值:

        -1:失败

        其他值:接收到的数据长度

        实例:

    int sock_fd;    //在sock_fd 进行监听,在 new_fd 接收新的链接
    char recvBuf[512] = {0};
    
    //服务器的地址信息
    struct sockaddr_in send_addr;
    socklen_t addr_length = sizeof(send_addr);

    //初始化预连接的服务端地址
    send_addr.sin_family = AF_INET;
    send_addr.sin_port = htons(_PROT_);
    send_addr.sin_addr.s_addr = inet_addr("192.168.3.198");
    addr_length = sizeof(send_addr);


    recvfrom(sock_fd, recvBuf, sizeof(recvBuf), 0, (struct sockaddr *)&send_addr, &addr_length);

      lwip_setsockopt

        函数功能:

        设置套接字描述符选项

        函数原型:

#define lwip_setsockopt   setsockopt
int setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen)

        参数:

        s:socket描述符,socket()函数返回

        level:选项定义的层次

SOL_SOCKET,套接字层
IPPROTO_TCP,TCP层
IPPROTO_IP,IP层
IPPROTO_IPV6,IPV6层

        optname:需要设置的选项。这里只介绍常用的选项。在level为SOL_COCKET(套接字层)时,optname可选一下值:

/*设置发送超时*/
#define SO_SNDTIMEO     0x1005 /* send timeout */
/*设置接收超时*/
#define SO_RCVTIMEO     0x1006 /* receive timeout */

         optval:指向存放选项待设置新值的缓冲区

        optlen:缓冲区长度

        返回值:

        -1:失败

        0:成功

        实例:

struct timeval timeout;
timeout.tv_sec  = 30;   //秒
timeout.tv_usec = 0;    //微秒
if (setsockopt(client, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)) < 0) {
    LOG_I(lwip_socket_example, "Setsockopt failed - set rcvtimeo\n");
}

      htonl()、htons()、ntohl()、ntohs()

        函数功能:

        在编程的时候,往往会遇到网络字节顺序主机顺序的问题。这时就需要以上四个函数进行调节了。

htonl()--"Host to Network Long"
 
ntohl()--"Network to Host Long"
 
htons()--"Host to Network Short"
 
ntohs()--"Network to Host Short"

        主机顺序大端或小端大端就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端(高位在前,低位在后)。小端就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端(低位在前,高位在后)。

        网络字节序:4个字节的32 bit值以下面的次序传输:首先是0~7bit,其次8~15bit,然后16~23bit,最后是24~31bit。这种传输次序称作大端字节序。由于TCP/IP首部中所有的二进制整数在网络中传输时都要求以这种次序,因此它又称作网络字节序

        函数原型:

uint32_t htonl(uint32_t hostlong);

        参数:

        转换前的值

        返回值:

        转换后的值

        实例:

server_sock.sin_addr.s_addr = htonl(INADDR_ANY);    //地址,随意分配

        

     inet_addr()      

        函数功能:   

        转换网络主机地址(192.168.x.x)为网络字节序排序地址

        函数原型:

in_addr_t inet_addr(const char* cp)

        参数:

        cp:网络主机地址(192.168.x.x)

        返回值:

        -1:失败。当cp无效时(255.255.255.0或其他)返回-1.

        其他值:网络字节排序地址

        实例:

send_addr.sin_addr.s_addr = inet_addr("192.168.3.198");

     inet_aton()      

        函数功能:   

        将主机地址(192.168.x.x)转化为二进制数值

        注:这个函数转换完后不能用于网络传输,还需要调用htonshtonl函数才能将主机字节顺序转换为网络字节顺序

        函数原型:

int inet_aton(const char* cp, struct in_addr* inp)

        参数:

        cp:输入值,网络主机地址(192.168.x.x)

        inp:输出值,转换后的二进制数值

        返回值:

        0:主机地址无效

        其他值:主机地址有效

        实例:

struct sockaddr_in sin1;	
inet_aton("127.0.0.1", &sin1.sin_addr);

     inet_ntoa()      

        函数功能:   

        将网络字节排序的地址转换为ASICC(x.x.x.x)。

        注:该字符串的空间为静态分配,这意味着在第二次调用该函数时,上一次调用的输出值将会被覆盖

        函数原型:

char *inet_ntoa(struct in_addr in)

        参数:

        in:类型为in_addr。网络字节排序地址。

typedef uint32_t in_addr_t;

        返回值:

        转化的字符串

        实例:

struct in_addr addr1,addr2;

addr1 = inet_addr("192.168.0.74");
addr2 = inet_addr("211.100.21.179");

printf("%s : %s\n", inet_ntoa(addr1), inet_ntoa(addr2)); //不可以这么用,结果会被覆盖  
printf("%s\n", inet_ntoa(addr1));   
printf("%s\n", inet_ntoa(addr2));

输出结果:
192.168.0.74 : 192.168.0.74          //从这里可以看出,printf里的inet_ntoa只运行了一次。

192.168.0.74  

211.100.21.179 

     inet_pton()      

        函数功能:   

        将点分十进制的IP地址(192.168.x.x)转化为用于网络传输的数据格式

        函数原型:

int inet_pton(int af, const char *src, void *dst)

        参数:

        af:地址族,AF_INET(IPV4)、AF_INET6(IPV6)。

        src:输入值,点分十进制的IP地址(192.168.x.x)

        dst:输出值,用于网络传输的数据格式

        返回值:

        -1:异常

        0:输入值异常

        1:成功

        实例:

struct sockaddr_in socket_addr;
inet_pton(AF_INET, "192.168.1.110", &socket_addr.sin_addr); 
/*
代替socket_addr.sin_addr.s_addr = inet_addr("192.168.1.110");	//IP地址转换
*/

     inet_ntop()      

        函数功能:   

        将用于网络传输的数据格式转化为点分十进制的IP地址格式(192.168.x.x)

        函数原型:

const char *inet_ntop(int af, const void *src, char *dst, socklen_t size)

        参数:

        af:地址族,AF_INET(IPV4)、AF_INET6(IPV6)。

        src:输入值,网络传输数据格式的数据

        dst:输出值,IP地址格式(192.168.x.x)

        size:输入值,目标存储单元大小。

        返回值:

        0:成功

        其他值:失败。ENOSPC size长度太小。

        实例:

char str[INET_ADDRSTRLEN];
struct sockaddr_in socket_addr;

char *ptr = inet_ntop(AF_INET,&socket_addr.sin_addr, str, sizeof(str));      
// 代替 ptr = inet_ntoa(socket_addr.sin_addr)

三、实例

        这里分别创建一个TCP和一个UDP

         现在BUILD.gn文件中添加如下代码

    include_dirs = [
        "//utild/native/lite/include",
        "//base/iot_hardware/interfaces/kits/wifiiot_lite",
        "//utils/native/lite/include",
        "//kernel/liteos_m/components/cmsis/2.0",
        "//foundation/communication/interfaces/kits/wifi_lite/wifiservice",
        "//vendor/hisi/hi3861/hi3861/third_party/lwip_sack/include/",
    ]
/*TCP*/


#include <stdio.h>
#include <unistd.h>

#include "ohos_init.h"
#include "cmsis_os2.h"

#include "wifi_device.h"
#include "lwip/netifapi.h"
#include "lwip/api_shell.h"
#include <netdb.h>
#include <string.h>
#include <stdlib.h>
#include "lwip/sockets.h"

#define LOG_I(fmt, args...)   printf("<%8ld> - [SOCKET_CLIENT]:"fmt"\r\n",osKernelGetTickCount(),##args);
#define LOG_E(fmt, args...)   printf("<%8ld>-[SOCKET_CLIENT_ERR]>>>>>>>>>>>>:"fmt"\r\n",osKernelGetTickCount(), ##args);

#define _PROT_ 7682


static const char *send_data = "Hello! I'm BearPi-HM_Nano UDP Client!\r\n";

static void SocketClientTask(void)
{
    int sock_fd;    //在sock_fd 进行监听,在 new_fd 接收新的链接
    char recvBuf[512] = {0};

    //连接Wifi
    extern int drv_wifi_connect(const char *ssid, const char *psk);
    drv_wifi_connect("Harmony_test_ap", "123123123");

    LOG_I("wifi connect success");

    //创建socket
    if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    {
        LOG_E("create socket failed!\r\n");
        exit(1);
    }

    LOG_I("socket TCP create done");

    struct sockaddr_in socket_addr;
    memset(&socket_addr, 0, sizeof(socket_addr));

    socket_addr.sin_family = AF_INET;	//IPV4
    socket_addr.sin_port = htons(_PROT_);	//端口
    socket_addr.sin_addr.s_addr = inet_addr("192.168.3.198");	//IP地址转换
    // socket_addr.sin_addr.s_addr = inet_addr(ipaddr_ntoa(&sta_if->gw));    //网关IP

    socklen_t addr_length = sizeof(socket_addr);

    LOG_I( "connect port:%d, addr:%s",_PROT_,inet_ntoa(socket_addr.sin_addr));

    int ret  = 0;
    do{
        ret = lwip_connect(sock_fd, (struct sockaddr *)&socket_addr, addr_length);
        if(ret < 0) //失败
        {
            LOG_I("socket connect fail");
            // lwip_close(sock_fd);    //关闭socket
            osDelay(100);
        }
    }while(1);

    LOG_I("socket connect success");

    struct timeval timeout;
    timeout.tv_sec = 5;       //秒
    timeout.tv_usec = 0;     //微秒
    if (lwip_setsockopt(sock_fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)) < 0) //设置接收超时
    {
        LOG_E("Setsockopt failed - set rcvtimeo\n");
    }

    LOG_I("set socket receive timeout:%d",timeout.tv_sec);

    int temp_len = 0;

    while(1)
    {
        bzero(recvBuf, sizeof(recvBuf));

        if(lwip_write(sock_fd,send_data, strlen(send_data)) != -1)
        {
            LOG_I("socket write success");
        }
        else
        {
            LOG_E("socket write fail");
        }

        temp_len = 0;
        if((temp_len = lwip_read(sock_fd, recvBuf, sizeof(recvBuf))) > 0) //读成功
        {
            LOG_I( "TCP client >>>>>read>>>>> data,len:%d,data:%s", temp_len, recvBuf);
        }
        else
        {
            LOG_E("socket client read fail");
        }
    }

    //关闭这个 socket
    closesocket(sock_fd);
}

void app_socket_client_init(void)
{
    osThreadAttr_t attr;

    attr.name = "UDPClientTask";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 10240;
    attr.priority = osPriorityNormal;

    if (osThreadNew((osThreadFunc_t)SocketClientTask, NULL, &attr) == NULL)
    {
        LOG_E("[UDPClientDemo] Falied to create UDPClientTask!\n");
    }
}
/*UDP*/


#include <stdio.h>
#include <unistd.h>

#include "ohos_init.h"
#include "cmsis_os2.h"

#include "wifi_device.h"
#include "lwip/netifapi.h"
#include "lwip/api_shell.h"
#include <netdb.h>
#include <string.h>
#include <stdlib.h>
#include "lwip/sockets.h"

#define LOG_I(fmt, args...)   printf("<%8ld> - [SOCKET_CLIENT]:"fmt"\r\n",osKernelGetTickCount(),##args);
#define LOG_E(fmt, args...)   printf("<%8ld>-[SOCKET_CLIENT_ERR]>>>>>>>>>>>>:"fmt"\r\n",osKernelGetTickCount(), ##args);

#define _PROT_ 7682


static const char *send_data = "This is a UDP client test!\r\n";

static void SocketClientTask(void)
{
    int sock_fd;    //在sock_fd 进行监听,在 new_fd 接收新的链接
    char recvBuf[512] = {0};

    //连接Wifi
    extern int drv_wifi_connect(const char *ssid, const char *psk);
    drv_wifi_connect("Harmony_test_ap", "123123123");

    LOG_I("wifi connect success");


    //创建socket
    if ((sock_fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
    {
        LOG_E("create socket failed!\r\n");
        exit(1);
    }

    LOG_I("socket UDP create done");

    //服务器的地址信息
    struct sockaddr_in send_addr;
    socklen_t addr_length = sizeof(send_addr);

    //初始化预连接的服务端地址
    send_addr.sin_family = AF_INET;
    send_addr.sin_port = htons(_PROT_);
    send_addr.sin_addr.s_addr = inet_addr("192.168.3.198");
    addr_length = sizeof(send_addr);

    //总计发送 count 次数据
    while (1)
    {
        bzero(recvBuf, sizeof(recvBuf));

        //发送数据到服务远端
        sendto(sock_fd, send_data, strlen(send_data), 0, (struct sockaddr *)&send_addr, addr_length);

        LOG_I("socket send done");

        //线程休眠一段时间
        sleep(10);
        // osDelay(500);

        LOG_I("socket wait receive data");

        //接收服务端返回的字符串
        recvfrom(sock_fd, recvBuf, sizeof(recvBuf), 0, (struct sockaddr *)&send_addr, &addr_length);
        LOG_I("%s:%d=>%s\n", inet_ntoa(send_addr.sin_addr), ntohs(send_addr.sin_port), recvBuf);
    } 

    //关闭这个 socket
    closesocket(sock_fd);
}

void app_socket_client_init(void)
{
    osThreadAttr_t attr;

    attr.name = "UDPClientTask";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 10240;
    attr.priority = osPriorityNormal;

    if (osThreadNew((osThreadFunc_t)SocketClientTask, NULL, &attr) == NULL)
    {
        LOG_E("[UDPClientDemo] Falied to create UDPClientTask!\n");
    }
}

        结果:因为使用的版本为1.0版本的SDK,TCP有问题,所以,这里先看UDP的结果,后续TCP会更换更改版本的SDK补上。

 

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

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

相关文章

ChatGPT发展报告:原理、技术架构详解和产业未来(附下载)

今年12月1日&#xff0c;OpenAI推出人工智能聊天原型ChatGPT&#xff0c;再次赚足眼球&#xff0c;为AI界引发了类似AIGC让艺术家失业的大讨论。 据报道&#xff0c;ChatGPT在开放试用的短短几天&#xff0c;就吸引了超过 100 万互联网注册用户。并且社交网络流传出各种询问或…

其他类型的CMOS逻辑门

1.CMOS与非门 电路结构如图所示 如图所示&#xff0c;T1、 T3为两个串联的PMOS&#xff0c; T2、 T4为两个并联的NMOS. A、B有一个为“0”时&#xff0c;T2、 T4至少有一个截止&#xff0c; T1、 T3至少有一个导通&#xff0c;故输出为高电平&#xff0c;Y&#xff1d;1. A、…

用Colab免费部署AI绘画云平台Stable Diffusion webUI

Google Colab 版的 Stable Diffusion WebUI 1.4 webui github 地址&#xff1a;https://github.com/sd-webui/stable-diffusion-webui 平台搭建 今天就来交大家如果来搭建和使用这个云平台。 第一步: 打开链接 https://colab.research.google.com/github/altryne/sd-webu…

求最大字段和(穷举法、动态规划、分治法)

目录 1、案例要求2、算法设计与实现2.1 穷举法2.1.1 算法设计思路2.1.2 代码实现 2.2 动态规划2.2.1 算法设计思路2.2.2 实现代码 2.3 分治法2.3.1 算法实现思路2.3.2 代码实现 3、总结 1、案例要求 给定由n个整数&#xff08;可能为负整数&#xff09;组成的序列a1,a2,…,an&…

菜鸟对原型链的理解

1.什么是原型 函数下的prototype属性&#xff0c;是个指针&#xff0c;指向的对象就是原型 2.什么是原型链 很多个原型连接起来就是一条链了。 function Person() { } var test new Person(); 当我们new一个构造函数是&#xff0c;实例对象&#xff08;test&#xff09;&a…

Windows平台上的5种敏捷软件开发(过程)模型

我是荔园微风&#xff0c;作为一名在IT界整整25年的老兵&#xff0c;今天总结一下Windows平台上的5种敏捷软件开发(过程)模型。 说到这个问题&#xff0c;你必须先知道除了敏捷模型还有没有其他什么模型&#xff1f;同时要比较模型的区别&#xff0c;首先还要看看什么叫软件开…

文件权限-chmod命令 – 改变文件或目录权限

Linux chmod命令 – 改变文件或目录权限 在Linux系统中&#xff0c;每个文件和目录都有自己的权限属性&#xff0c;这些属性包括读、写、执行等权限。通常情况下&#xff0c;只有文件的所有者和管理员可以设置文件权限&#xff0c;而普通用户只能管理自己文件的权限。为了更好…

数据结构总结5:堆

后续会有补充 堆 堆是一种数据结构&#xff0c;总是一棵完全二叉树&#xff0c;是使用数组存储的&#xff0c;是非线性的&#xff1b;并且要求树中所有的父亲都小于等于孩子&#xff08;小根堆&#xff09;/树中所有的父亲都大于等于孩子&#xff08;大根堆&#xff09;不一定…

人工智能基础部分16-神经网络与GPU加速训练的原理与应用

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能基础部分16-神经网络与GPU加速训练的原理与应用&#xff0c;在深度学习领域&#xff0c;神经网络已经成为了一种流行的、表现优秀的技术。然而&#xff0c;随着神经网络的规模越来越大&#xff0c;训练神经…

Linux下部署Samba服务(实现windows和linux共享)

关于Linux和Windows系统之间的文件传输&#xff0c;很多人选择使用FTP&#xff0c;相对较安全&#xff0c;但是有时还是会出现一些问题&#xff0c;比如上传文件时&#xff0c;文件名莫名出现乱码&#xff0c;文件大小改变等问题。相比较来说&#xff0c;使用Samba作为文件共享…

Midjourney会员充值教程

本教程收集于:AIGC从入门到精通教程 Midjourney会员充值教程 目录 一、 打开会员订阅页面 二、 选择您需要订阅的会员

8. 机器学习系统设计

假设你想建立一个垃圾邮件分类器&#xff0c;通过监督学习来构造一个分类器来区分垃圾邮件和非垃圾邮件。为了应用监督学习&#xff0c;首先要想的就是&#xff1a;如何来表示邮件的特征向量x&#xff0c;通过特征向量x和分类标签y&#xff0c;我们就能训练一个分类器&#xff…

(十六)数据编辑——图形编辑②

数据编辑——图形编辑② 目录 数据编辑——图形编辑②1.5线要素的延长和裁剪1.5.1线要素延长1.5.2线要素裁剪 1.6要素的变形与缩放1.6.1要素变形操作1.6.2要素缩放操作 1.7要素结点的编辑1.7.1添加结点1.7.2删除结点1.7.3移动结点 1.5线要素的延长和裁剪 单击编辑器下拉菜单&a…

【Nvidia Jetson Xavier NX/AGX/NANO】上用docker跑pytorch等cv推理应用

Nvidia Jetson Xavier NX/AGX docker WHY镜像地址使用方法docker常用命令备忘jtop安装关于保存容器镜像关于使用dockerfile构建关于映射外部路径让容器访问外部文件关于性能 WHY 在jetson上使用docker跑opencv和pytorch其实主要是要找对镜像&#xff0c;docker官方的hub里并没…

linux0.12-9-5-ramdisk.c

1、 需要配合其他代码一起看&#xff0c;才能有深刻的理解。 [432页] 9-5 ramdisk.c程序 9-5-1 功能描述 本文件是内存虚拟盘(Ram Disk)驱动程序&#xff0c;由Theodore Ts’o编制。虚拟盘设备是一种利用物理内存来模拟实际磁盘存储数据的方式。其目的主要是为了提高对&quo…

Conda 安装Pytorch

1、conda 切换虚拟环境 activate 虚拟环境名称 C:\Windows\System32>activate python310 温馨提示&#xff1a;查询虚拟环境列表 conda env list C:\Windows\System32>conda env list # conda environments: # base D:\anaconda3 python310 …

15-01通信安全

网络设备安全——防火墙 状态检测 应用级代理 防火墙实战 默认禁止&#xff1a;Ingress和Egress高安全域优先&#xff1a;允许高安全域发起请求规则具体&#xff1a;源地址&#xff08;标签&#xff09;、源端口&#xff0c;目标地址&#xff08;标签&#xff09;、目标端口、…

CSAPP复习(1)

分析方法只讲了amuda定理 Hello的一生 hello的执行过程 了解hello的执行过程 和响应的汇编器生成的可执行文件是.out不是.exe gcc -E hello.c -o hello.i//预处理 cpp hello.c>hello.i gcc -S hello.i -o hello.s//编译 gcc -C hello.s -o hello.o//汇编 二进制文件看不到…

【PDF软件篇】PDF轻量化电子笔记编辑利刃-Xodo软件优化

【PDF软件篇】PDF轻量化电子笔记编辑利刃-Xodo软件优化 默认配置已经够强&#xff0c;但是我还是推荐自定义&#xff0c;适合自己的就是最好的—【蘇小沐】 文章目录 【PDF软件篇】PDF轻量化电子笔记编辑利刃-Xodo软件优化1.实验环境 &#xff08;一&#xff09;日常办公导出无…