嵌入式Linux学习笔记(7)-Socket网络编程

news2024/9/24 7:59:50

一、什么是Socket网络编程

        Socket是一种抽象的编程接口,可以用于在不同主机之间进行数据通信。Socket API提供了一系列函数来创建、连接、发送和接收数据等操作。嵌入式 Linux 系统中的 Socket 网络编程是指在嵌入式系统中使用 Socket API 进行网络通信。

        Socket 网络编程可以实现各种网络通信功能,如 TCP/IP 通信和 UDP 通信。

二、TCP 与 UDP

        TCP是一种面向连接的协议,它提供可靠的数据传输。它通过建立一个连接,将数据分为多个小的数据包,并保证它们按顺序传输到目标节点。如果有数据包丢失或损坏,TCP会进行重传,确保所有数据包都被传输,并且按顺序重新组装。TCP还提供了流量控制和拥塞控制的机制,以确保网络稳定和高效。 TCP适用于需要可靠传输、顺序传输和流量控制的应用程序,如网页浏览、文件传输和电子邮件等。

        UDP是一种无连接的协议,它提供不可靠的数据传输。UDP将数据分成小的数据包,并将它们发送到目标节点,但不保证它们按顺序送达。UDP不进行重传,也不提供流量控制和拥塞控制。因此,UDP的传输速度相对较快,但在不可靠的网络环境下可能会有数据丢失或乱序。UDP适用于对实时性要求较高,但对数据可靠性要求不高的应用程序,如视频流传输、语音通话和在线游戏等。

TCP/IP通信流程:

        TCP/IP通信通过三次握手建立连接,四次挥手关闭连接

    1. 客户端向服务器发起连接请求,使用传输控制协议(TCP)的三次握手握手建立连接。

    2. 服务器接收到连接请求后,回复一个确认信息给客户端,进行第二次握手。

    3. 客户端接收到确认信息后,再次向服务器发送一个确认信息,进行第三次握手。

    4. 服务器接收到确认信息后,连接建立成功,开始进行数据传输。

    5. 客户端将需要传输的数据分成较小的数据包,并为每个数据包分配一个序列号,并将数据包传输给服务器。

    6. 服务器接收到数据包后,发送一个确认信息给客户端,表示已经接收到数据。

    7. 客户端接收到确认信息后,再次向服务器发送下一个数据包。

    8. 服务器不断接收和发送数据包,直到所有数据传输完成。

    9. 数据传输完成后,客户端发送一个连接释放请求给服务器,并等待服务器回复,进行第一次挥手。

    10. 服务器接收到连接释放请求后,发送一个确认信息给客户端,表示同意释放连接,进行第二次挥手。

    11. 客户端接收到确认信息后,不可以再向服务端发送消息,但仍可以接收服务端发送的消息。

    12. 服务端如果没有要发送的消息,此时发送一个连接释放请求给客户端,并等待客户端回复,进行第三次挥手。

    13. 客户端接收到连接释放请求后,发送一个确认信息给服务端,表示同意释放连接,进行第四次挥手。此时客户端关闭。

    14. 服务端接收到确认信息后关闭。

UDP通信流程:

        UDP通信不需要建立连接和释放连接

    1. 客户端将需要传输的数据打包成数据报,并指定目标主机的IP地址和端口号。

    2. 客户端将数据报发送给目标主机。

    3. 服务器接收到数据报后,根据目标端口号对数据进行处理。

    4. 服务器根据需要向客户端发送响应数据报。

    5. 客户端接收到服务器的响应数据报后,进行相应的处理。

    6. 数据传输完成后,连接自动关闭,不需要进行连接释放。

三、相关函数

        在C语言中提供了一系列的函数来创建、连接、发送和接收网络数据。下面是一些常见的Socket网络编程相关函数和它们的用法:

1、TCP 相关函数

        socket()函数:创建一个新的Socket,并返回一个文件描述符。它接受三个参数:地址域(AF_INET表示IPv4)、类型(SOCK_STREAM表示TCP)和协议(0表示根据类型自动选择协议)。示例用法:

int sockfd;
sockfd = socket(AF_INET, SOCK_STREAM, 0);

        bind()函数:将Socket绑定到一个特定的本地地址和端口。它接受三个参数:Socket文件描述符、指向本地地址结构的指针和本地地址结构的大小。示例用法:

struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT);
addr.sin_addr.s_addr = INADDR_ANY;
bind(sockfd, (struct sockaddr *)&addr, sizeof(addr));

        listen()函数:将Socket设置为监听状态,等待连接请求。它接受两个参数:Socket文件描述符和最大连接数。示例用法:

listen(sockfd, BACKLOG);

        accept()函数:接受客户端的连接请求,并返回一个新的Socket文件描述符,用于后续的数据传输。它接受三个参数:Socket文件描述符、指向客户端地址结构的指针和客户端地址结构的大小。示例用法:

int new_sockfd;
new_sockfd = accept(sockfd, (struct sockaddr *)&client_addr, &addrlen);

        connect()函数:与远程服务器建立连接。它接受三个参数:Socket文件描述符、指向远程地址结构的指针和远程地址结构的大小。示例用法:

struct sockaddr_in serv_addr;
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
inet_pton(AF_INET, "127.0.0.1", &(serv_addr.sin_addr));
connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));

        send()函数:发送数据到连接的Socket。它接受四个参数:Socket文件描述符、指向数据的指针、数据的大小和附加参数。示例用法:

char message[] = "Hello, World!";
send(sockfd, message, strlen(message), 0);

        recv()函数:从连接的Socket接收数据。它接受四个参数:Socket文件描述符、指向接收缓冲区的指针、缓冲区的大小和附加参数。示例用法:

char buffer[MAX_BUFFER_SIZE];
int bytes_received = recv(sockfd, buffer, MAX_BUFFER_SIZE - 1, 0);

        close()函数:关闭Socket连接。它接受一个参数:Socket文件描述符。示例用法:

close(sockfd);

2、UDP相关函数

        UDP 其余函数与 TCP 相同,只是发送和接收函数略有不同。

        sendto()函数:向指定的目标地址发送数据。它接受六个参数:套接字文件描述符、数据缓冲区、数据大小、附加参数(通常为0)、目标地址结构的指针和目标地址结构的大小。

char message[] = "Hello, World!";
struct sockaddr_in client_addr;
client_addr.sin_family = AF_INET;
client_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
client_addr.sin_port = htons(PORT);

sendto(sockfd, message, strlen(message), 0, (struct sockaddr*)&client_addr, sizeof(client_addr));

        recvfrom()函数:从指定的源地址接收数据。它接受六个参数:套接字文件描述符、接收缓冲区、缓冲区大小、附加参数(通常为0)、源地址结构的指针和源地址结构的大小。

char buffer[1024];
struct sockaddr_in client_addr;
int addr_len = sizeof(client_addr);

recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr*)&client_addr, &addr_len);

        注意:UDP是无连接的,所以在发送数据时不需要先建立连接。发送数据时,可以指定目标地址,也可以不指定(这时可以直接使用send()函数)。接收数据时,可以获取到数据的源地址。

四、基于TCP的Socket通信

1、通信流程

服务器端(server)的流程大致如下:

  1. 创建Socket:使用socket()函数创建一个Socket,并指定协议族和Socket类型。

  2. 绑定Socket:使用bind()函数将Socket与特定的IP地址和端口号绑定。

  3. 监听连接:使用listen()函数将Socket设置为监听状态。

  4. 接受连接:使用accept()函数接受客户端的连接请求,并创建一个新的Socket用于与客户端通信。

  5. 与客户端通信:使用send()函数向客户端发送数据,使用recv()函数从客户端接收数据。

  6. 关闭连接:使用close()函数关闭Socket连接。

客户端(client)的流程大致如下:

  1. 创建Socket:使用socket()函数创建一个Socket,并指定协议族和Socket类型。

  2. 连接服务器:使用connect()函数与服务器建立连接。

  3. 与服务器通信:使用send()函数向服务器发送数据,使用recv()函数从服务器接收数据。

  4. 关闭连接:使用close()函数关闭Socket连接。

 2、编写实例

        server.c

#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <pthread.h>

#include <unistd.h>
#define handle_error(cmd, result) \
    if (result < 0)               \
    {                             \
        perror(cmd);              \
        return -1;                \
    }

void *read_from_client(void *argv){
    // 使用recv接收客户端发送的数据打印到控制台
    char *read_buf = NULL;
    int client_fd = *(int *)argv;
    read_buf = malloc(sizeof(char*) * 1024);
    ssize_t count = 0;

    if (!read_buf)
    {
        perror("malloc server read_buf");
        return NULL;
    }
    //接收数据  只要能接收到数据 一直挂起
    while(count = recv(client_fd,read_buf,1024,0))
    {
        if (count < 0)
        {
            perror("malloc server read_buf");
            return NULL;
        }

        fputs(read_buf,stdout);
    }
    
    printf("客户端请求关闭\n");
    free(read_buf);

    return NULL;

}

void *write_from_client(void *argv){
    // 接受控制台输入的消息 发送出去
    char *write_buf = NULL;
    int client_fd = *(int *)argv;
    write_buf = malloc(sizeof(char*) * 1024);
    ssize_t count = 0;

    if (!write_buf)
    {
        perror("malloc server write_buf");
        return NULL;
    }

    while(fgets(write_buf,1024,stdin) != NULL)
    {
        //发送数据
        count = send(client_fd,write_buf,1024,0);

        if (count < 0)
        {
            perror("send");
            return NULL;
        }

    }
    
    printf("接收到关闭请求,不再写入,关闭连接\n");
    // 可以具体关闭某一端
    shutdown(client_fd,SHUT_WR);
    free(write_buf);

    return NULL;

}

int main(int argc, char const *argv[])
{
    int sockfd,clientfd,temp_result;
    pthread_t pid_read,pid_write;
    // 创建服务器地址和客户端地址
    struct sockaddr_in server_addr,client_addr;
    // 清空
    memset(&server_addr,0,sizeof(server_addr));
    memset(&client_addr,0,sizeof(client_addr));

    // 填写服务端地址
    server_addr.sin_family = AF_INET;//协议
    // 填写ip地址 0.0.0.0
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    // inet_pton(AF_INET,"0.0.0.0",&server_addr.sin_addr);
    // 填写端口号
    server_addr.sin_port = htons(6666);

    // 网络编程流程
    // 1. socket
    sockfd = socket(AF_INET,SOCK_STREAM,0);//IPV4,TCP
    handle_error("socket",sockfd);
    
    // 2. 绑定地址
    temp_result = bind(sockfd,(struct sockaddr *)&server_addr,sizeof(server_addr));
    handle_error("bind",temp_result);

    // 3. 进入监听状态
    temp_result = listen(sockfd,128);
    handle_error("listen",temp_result);

    // 4. 获取客户端连接
    socklen_t client_addr_len = sizeof(client_addr);
    // 返回的 clienfd 才是能够和客户端收发消息的文件描述符
    clientfd = accept(sockfd,(struct sockaddr *)&client_addr,&client_addr_len);// 如果没有客户端连接会挂起等待
    handle_error("accpet",clientfd);

    printf("与客户端%s %d 建立连接,文件描述符是 %d\n",inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port),clientfd);

    // 创建线程用于收消息
    pthread_create(&pid_read,NULL,read_from_client,(void *)&clientfd);

    // 创建线程用于发消息
    pthread_create(&pid_write,NULL,write_from_client,(void *)&clientfd);

    // 阻塞主线程
    pthread_join(pid_read,NULL);
    pthread_join(pid_write,NULL);

    // 释放资源
    printf("释放资源\n");
    close(clientfd);
    close(sockfd);

    return 0;
}

        client.c

#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <pthread.h>

#include <unistd.h>
#define handle_error(cmd, result) \
    if (result < 0)               \
    {                             \
        perror(cmd);              \
        return -1;                \
    }

void *read_from_server(void *argv){
    // 使用recv接收客户端发送的数据打印到控制台
    char *read_buf = NULL;
    int client_fd = *(int *)argv;
    read_buf = malloc(sizeof(char*) * 1024);
    ssize_t count = 0;

    if (!read_buf)
    {
        perror("malloc server read_buf");
        return NULL;
    }
    //接收数据  只要能接收到数据 一直挂起
    while(count = recv(client_fd,read_buf,1024,0))
    {
        if (count < 0)
        {
            perror("malloc server read_buf");
            return NULL;
        }

        fputs(read_buf,stdout);
    }
    
    printf("服务端请求关闭\n");
    free(read_buf);

    return NULL;

}

void *write_from_server(void *argv){
    // 接受控制台输入的消息 发送出去
    char *write_buf = NULL;
    int client_fd = *(int *)argv;
    write_buf = malloc(sizeof(char*) * 1024);
    ssize_t count = 0;

    if (!write_buf)
    {
        perror("malloc server write_buf");
        return NULL;
    }

    while(fgets(write_buf,1024,stdin) != NULL)
    {
        //发送数据
        count = send(client_fd,write_buf,1024,0);

        if (count < 0)
        {
            perror("send");
            return NULL;
        }

    }
    
    printf("接收到关闭请求,不再写入,关闭连接\n");
    // 可以具体关闭某一端
    shutdown(client_fd,SHUT_WR);
    free(write_buf);

    return NULL;

}

int main(int argc, char const *argv[])
{
    int sockfd,temp_result;
    pthread_t pid_read,pid_write;
    // 创建服务器地址和客户端地址
    struct sockaddr_in server_addr,client_addr;
    // 清空
    memset(&server_addr,0,sizeof(server_addr));
    memset(&client_addr,0,sizeof(client_addr));

    // 填写客户端地址
    client_addr.sin_family = AF_INET;//协议
    // 填写ip地址 192.168.1.195
    inet_pton(AF_INET,"192.168.1.195",&client_addr.sin_addr);
    // 填写端口号
    client_addr.sin_port = htons(8888);

    // 填写服务端地址
    server_addr.sin_family = AF_INET;//协议
    // 填写ip地址 0.0.0.0/127.0.0.1
    inet_pton(AF_INET,"0.0.0.0",&server_addr.sin_addr);
    // 填写端口号
    server_addr.sin_port = htons(6666);


    // 客户端网络编程流程
    // 1. 创建socket
    sockfd = socket(AF_INET,SOCK_STREAM,0);
    handle_error("socket",sockfd);

    // 2. 绑定
    temp_result = bind(sockfd,(struct sockaddr *)&client_addr,sizeof(client_addr));
    handle_error("bind",temp_result);

    // 3. 主动连接服务端
    temp_result = connect(sockfd,(struct sockaddr *)&server_addr,sizeof(server_addr));
    handle_error("connect",temp_result);

    printf("连接上服务器%s %d\n",inet_ntoa(server_addr.sin_addr),ntohs(server_addr.sin_port));


    // 创建线程用于收消息
    pthread_create(&pid_read,NULL,read_from_server,(void *)&sockfd);

    // 创建线程用于发消息
    pthread_create(&pid_write,NULL,write_from_server,(void *)&sockfd);

    // 阻塞主线程
    pthread_join(pid_read,NULL);
    pthread_join(pid_write,NULL);

    // 释放资源
    printf("释放资源\n");
    close(sockfd);

    return 0;
}

五、基于UDP的Socket通信

1、通信流程

客户端(client)的流程大致如下:

        创建Socket:使用socket()函数创建一个Socket,并指定协议族和Socket类型。

        发送数据:使用sendto()函数将要发送的数据以及服务器的IP地址和端口号发送给服务器。

        接收数据:使用recvfrom()函数从服务器接收数据。

        关闭Socket:使用close()函数关闭Socket连接。

服务器端(server)的流程大致如下:

        创建Socket:使用socket()函数创建一个Socket,并指定协议族和Socket类型。

        绑定Socket:使用bind()函数将Socket与特定的IP地址和端口号绑定。

        接收数据:使用recvfrom()函数从客户端接收数据。

        处理数据:服务器对接收到的数据进行处理,可以根据需要进行相应的操作。

        发送数据:使用sendto()函数将处理后的数据发送给客户端。

        关闭Socket:使用close()函数关闭Socket连接。

2、编写实例

        server.c

#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>

#define handle_error(cmd, result) \
    if (result < 0)               \
    {                             \
        perror(cmd);              \
        return -1;                \
    }

int main(int argc, char const *argv[])
{
    // 使用UDP协议完成客户端与服务端的通信
    // EOF作为关闭的信号
    int sockfd,temp_result;
    char *buf = malloc(sizeof(char) * 1024);

    // 创建服务器地址和客户端地址
    struct sockaddr_in server_addr,client_addr;
    // 清空
    memset(&server_addr,0,sizeof(server_addr));
    memset(&client_addr,0,sizeof(client_addr));

    // 填写服务端地址
    server_addr.sin_family = AF_INET;//协议
    // 填写ip地址 0.0.0.0
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    // inet_pton(AF_INET,"0.0.0.0",&server_addr.sin_addr);
    // 填写端口号
    server_addr.sin_port = htons(6666);

    // UDP编程流程
    // 1. socket
    sockfd = socket(AF_INET,SOCK_DGRAM,0);//IPV4,TCP
    handle_error("socket",sockfd);

    // 2. 服务端绑定地址
    socklen_t server_len = sizeof(server_addr);
    socklen_t client_len = sizeof(client_addr);
    temp_result = bind(sockfd,(struct sockaddr *)&server_addr,server_len);
    handle_error("bind",temp_result);

    // 直接收发数据
    do
    {
        // 接收数据存到缓冲
        memset(buf,0,1024);
        temp_result = recvfrom(sockfd,buf,1024,0,(struct sockaddr*)&client_addr,&client_len);
        handle_error("recvfrom",temp_result);

        if (strncmp(buf,"EOF",3) != 0)
        {
            printf("接收到客户端%s %d信息: %s\n",inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port),buf);
            strcpy(buf,"OK");
        }else{
            printf("准备关闭\n");
        }
        
        temp_result = sendto(sockfd,buf,4,0,(struct sockaddr*)&client_addr,client_len);
        handle_error("sendto",temp_result);

    } while (strncmp(buf,"EOF",3) != 0);
    
    free(buf);
    
    return 0;
}

        client.c

#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>

#define handle_error(cmd, result) \
    if (result < 0)               \
    {                             \
        perror(cmd);              \
        return -1;                \
    }

int main(int argc, char const *argv[])
{
    // 使用UDP协议完成客户端与服务端的通信
    // EOF作为关闭的信号
    int sockfd,temp_result;
    char *buf = malloc(sizeof(char) * 1024);

    // 创建服务器地址和客户端地址
    struct sockaddr_in server_addr,client_addr;
    // 清空
    memset(&server_addr,0,sizeof(server_addr));
    memset(&client_addr,0,sizeof(client_addr));

    // 填写服务端地址
    server_addr.sin_family = AF_INET;//协议
    // 填写ip地址 0.0.0.0
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    // inet_pton(AF_INET,"0.0.0.0",&server_addr.sin_addr);
    // 填写端口号
    server_addr.sin_port = htons(6666);

    // UDP编程流程
    // 1. socket
    sockfd = socket(AF_INET,SOCK_DGRAM,0);//IPV4,TCP
    handle_error("socket",sockfd);

    // 2. 客户端不需要绑定地址
    socklen_t server_len = sizeof(server_addr);
    socklen_t client_len = sizeof(client_addr);
    // temp_result = bind(sockfd,(struct sockaddr *)&server_addr,server_len);
    // handle_error("bind",temp_result);

    // 直接收发数据
    do
    {
        write(STDOUT_FILENO,"Type something you want to send: ", 34);
        // 从控制台读取信息
        int buf_len = read(STDIN_FILENO,buf,1023);
        sendto(sockfd,buf,buf_len,0,(struct sockaddr *)&server_addr,server_len);
        handle_error("sendto",buf_len);

        // 清空缓冲区
        memset(buf,0,1024);

        temp_result = recvfrom(sockfd,buf,1024,0,NULL,NULL);
        handle_error("recvfrom",temp_result);

        if (strncmp(buf,"EOF",3) != 0)
        {
            printf("接收到服务端%s %d返回的数据: %s\n",inet_ntoa(server_addr.sin_addr),ntohs(server_addr.sin_port),buf);
        }
        

    } while (strncmp(buf,"EOF",3) != 0);

    free(buf);
    
    return 0;
}

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

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

相关文章

HTTP协议1.1请求头和keep-alive

请求头分类 End-to-end&#xff08;端对端&#xff09; 必须全部带给目标服务器&#xff0c;不会被中途变化或去掉 Hop-by-hop&#xff08;逐跳头&#xff09; 比如客户端发请求&#xff0c;要路过代理(例如Nginx)&#xff0c;头可以被自动删掉&#xff0c;来到真正服务器上…

vue/配置axios(前后端数据连通/api接口的调用)

1.创建apis文件 2.写入调用的api地址且暴露出去。 import httpInstance from /utils/http;export function getHomeNav() {return httpInstance({url: http://10.0.11.91:91/dailyreport/getdailyreportall,}) }3.创建文件编写拦截器 代码部分 //axios基础封装 import axio…

Thinkphp5x远程命令执行 靶场攻略

环境配置 靶场&#xff1a;vulhub/thinkphp/5-rce docker-compose up -d #启动环境 漏洞复现 1.访问靶场&#xff1a;http://172.16.1.198:8080/ 2.远程命令执⾏ POC&#xff1a; ?sindex/think\app/invokefunction&functioncall_user_func_array&vars[0]system…

Bytebase 2.23.0 - 支持 Entra (Azure AD) 用户/组同步

&#x1f680; 新功能 支持从 Entra ID&#xff08;前 Azure AD&#xff09;同步用户和群组。 支持 CockroachDB。 支持项目级别的默认备份设置&#xff0c;包含自动启用和跳过错误选项。 SQL 编辑器支持实时语法检查。 支持配置密码限制策略。 &#x1f514; 重大变更 分类…

初试AngularJS前端框架

文章目录 一、框架概述二、实例演示&#xff08;一&#xff09;创建网页&#xff08;二&#xff09;编写代码&#xff08;三&#xff09;浏览网页&#xff08;四&#xff09;运行结果 三、实战小结 一、框架概述 AngularJS 是一个由 Google 维护的开源前端 JavaScript 框架&am…

输电线塔目标检测数据集yolo格式该数据集包括2644张输电线塔高清图像,该数据集已经过yolo格式标注,具有完整的txt标注文件和yaml配置文件。

输电线塔目标检测数据集yolo格式 该数据集包括2644张输电线塔高清图像&#xff0c;该数据集已经过yolo格式标注&#xff0c;具有完整的txt标注文件和yaml配置文件。 输电线塔目标检测数据集 数据集名称 输电线塔目标检测数据集&#xff08;Transmission Tower Object Detecti…

从视觉到现实:掌握计算机视觉技术学习路线的十大步骤

成长路上不孤单&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【14后&#x1f60a;///C爱好者&#x1f60a;///计算机爱好者&#x1f60a;///持续分享所学&#x1f60a;///如有需要欢迎收藏转发///&#x1f60a;】 今日分享关于【计算机视…

【第十五章:Sentosa_DSML社区版-机器学习之关联规则】

目录 15.1 频繁模式增长 15.2 PrefixSpan 【第十五章&#xff1a;Sentosa_DSML社区版-机器学习之关联规则】 机器学习关联规则是一种用于发现数据集中项之间有趣关系的方法。它基于统计和概率理论&#xff0c;通过分析大量数据来识别项之间的频繁共现模式。 15.1 频繁模式增…

Linux-DHCP服务器搭建

环境 服务端&#xff1a;192.168.85.136 客户端&#xff1a;192.168.85.138 1. DHCP工作原理 DHCP动态分配IP地址。 2. DHCP服务器安装 2.1前提准备 # systemctl disable --now firewalld // 关闭firewalld自启动 # setenforce 0 # vim /etc/selinux/config SELINU…

学生管理系统模块化编程

项目介绍&#xff1a;Java基础mysql的一个简单练习 一.数据库 二.项目结构 lib下的jar包下载地址&#xff1a;Maven Repository: mysql mysql-connector-java (mvnrepository.com) 1.db.properties drivercom.mysql.jdbc.Driver urljdbc:mysql://localhost:3306/student?u…

【Unity3d Shader】毛玻璃效果

毛玻璃也叫​磨砂玻璃​:是用物理或化学方法处理过的一种表面粗糙不平整的半透明玻璃。 毛玻璃成像原理:毛玻璃表面不平整,光线通过毛玻璃被反射后向四面八方射出去(因为毛玻璃表面不是光滑的平面,使光产生了漫反射),折射到视网膜上已经是不完整的像,于是就看不清楚(…

基于OpenCV的单目测距

随着计算机视觉技术的发展&#xff0c;单目测距作为一种重要的视觉测量手段&#xff0c;在众多领域得到了广泛的应用。本文将探讨基于OpenCV的单目测距原理、局限性、实际应用场景以及一些优化方案。 单目测距的原理 单目测距是指利用一台摄像机拍摄到的单一图像来进行距离测量…

2016年国赛高教杯数学建模D题风电场运行状况分析及优化解题全过程文档及程序

2016年国赛高教杯数学建模 D题风电场运行状况分析及优化 风能是一种最具活力的可再生能源&#xff0c;风力发电是风能最主要的应用形式。我国某风电场已先后进行了一、二期建设&#xff0c;现有风机124台&#xff0c;总装机容量约20万千瓦。请建立数学模型&#xff0c;解决以下…

【Python报错已解决】ValueError: cannot convert float NaN to integer

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 专栏介绍 在软件开发和日常使用中&#xff0c;BUG是不可避免的。本专栏致力于为广大开发者和技术爱好者提供一个关于BUG解决的经…

网页设计html心得

一&#xff0c;认识网页 说到网页&#xff0c;其实大家并不陌生 1.1网页究竟是什么&#xff1f; 网页主要由文字、图像和超链接等元素构成。当然&#xff0c;除了这些元素&#xff0c;网页中还可以包含音频、视频以及Flash等。 1.2网页是如何形成的呢&#xff1f; 1.特殊的…

C++读取txt文件中的句子在终端显示,同时操控鼠标滚轮(涉及:多线程,产生随机数,文件操作等)

文章目录 运行效果功能描述代码mian.cppincludeMouseKeyControl.hTipsManagement.h srcMouseControl.cppTipsManagement.cpp 运行效果 功能描述 线程一&#xff1a;每隔n随机秒&#xff0c;动一下鼠标滚轮&#xff0c;防止屏幕息屏。 线程二&#xff1a;运行时加载txt文件中的…

前端html+css+js 基础总结

​​​HTML 行级元素 标签分为行级元素与块级元素 行级元素占据区域由其显示内容决定&#xff0c;如span&#xff0c;img(图片)&#xff0c;<a></a>基本格式: <a href"链接" target"_blank"></a>用于跳转到其他网站&#xff0c…

蓝桥杯1.小蓝的漆房

样例输入 2 5 2 1 1 2 2 1 6 2 1 2 2 3 3 3样例输出 1 2 import math import os import sys tint(input())#执行的次数 for j in range(t):n,kmap(int,input().split())#n为房间数 k为一次能涂的个数alist(map(int,input().split()))#以列表的形式存放房间的颜色maxvaluemath…

环形缓冲区例子

即使使用中断函数或者定时器函数记录按键&#xff0c;如果只能记录一个键值的话&#xff0c;如果不能 及时读走出来&#xff0c;再次发生中断时新值就会覆盖旧值。要解决数据被覆盖的问题&#xff0c;可以使用 一个稍微大点的缓冲区&#xff0c;这就涉及数据的写入、读出&#…