当前位置: 首页 > news >正文

网络编程:OSI协议,TCP/IP协议,IP地址,UDP编程

目录

国际网络通信协议标准:

1.OSI协议:

 2.TCP/IP协议模型:

 应用层  :

 传输层:

  网络层:             IPV4协议            IP地址

 IP地址的划分:            公有地址            私有地址

        MAC地址:

        端口号:

 UDP编程

1.套接字:

2.流程  

3.函数接口

(1) socket

 (2)sendto 

(3) inet_addr

(4) htons 

(5) bind 

(6)recvfrom 

 主机作为发送端

主机作为接收端


 网络:
协议:通信双方约定的一套标准 

国际网络通信协议标准:

1.OSI协议:

        应用层          发送的数据内容
        表示层          数据是否加密
        会话层          是否建立会话连接
        传输层          数据传输的方式
        网络层          数据的路由
        数据链路层      局域网内部通信
        物理层          物理介质的连接

 2.TCP/IP协议模型:

 
        应用层          发送的数据内容
        传输层          数据传输的方式
        网络层          数据由一台主机到达另一台主机
        网络接口层      物理介质连接 

 应用层  :


            FTP     文件传输协议    
            TFTP    简单文件传输协议
            HTTP    超文本传输协议
            HTTPS   安全超文本传输协议
            SMTP    简单邮件传输协议
            TELNET  网络终端登录协议
            DNS     域名系统
            .. 

 传输层:

    TCP     传输控制协议
     UDP     用户数据报协议

            UDP:不安全、不可靠的传输方式
                 UDP机制简单
                 UDP占用的资源开销比较小
            TCP:安全、可靠的传输方式
                 TCP机制复杂
                 TCP占用的资源开销比较大 
                    三次握手建立连接,确认双方能够通信
                    通信过程中保障数据传输的完整性
                    四次挥手断开连接,确保数据传输的完整

  网络层: 
            IPV4协议
            IP地址

            管理员IP地址形式:192.168.0.167
            内存IP地址形式:  11000000.10101000.00000000.10100111

            IP地址 = 网络位 + 主机位 
            网络位:IP地址所属的网段(局域网的编号)
            主机位:局域网中的第几台主机
            网段号:网络位不变,主机位全为0 
            广播号:网络位不变, 主机位全为1 
            子网掩码:每个IP地址都会搭配一个子网掩码,用来区分IP地址的网络位及主机位
                     子网掩码展开成二进制,1对应的部分就是IP地址的网络位,0对应的部分就是IP地址的主机位
            192.168.0.167
            255.255.255.0
            11000000.10101000.00000000.10100111
            11111111.11111111.11111111.00000000

            网段号192.168.0.0
            广播号192.168.0.255

 IP地址的划分:
            公有地址
            私有地址

            A类:1.0.0.0 ~ 126.255.255.255
                子网掩码:255.0.0.0 
                管理超大规模型网络
                私有地址:10.0.0.0 ~ 10.255.255.255

            B类:128.0.0.0 ~ 191.255.255.255
                子网掩码:255.255.0.0 
                管理大中规模型网络
                私有地址:172.16.0.0 - 172.31.255.255

            C类:192.0.0.0 ~ 223.255.255.255
                子网掩码:255.255.255.0
                管理中小规模型网络
                私有地址:192.168.0.0 ~ 192.168.255.255

            D类:224.0.0.0 ~ 239.255.255.255
                用于组播:255.255.255.0

            E类:240.0.0.0 ~ 255.255.255.255
                用于实验和研究:255.255.255.0

        MAC地址:

 设备自带网卡的地址(该地址是唯一的)


        端口号:

 找到同一台主机不同的应用程序

 UDP编程

1.套接字:


        实现Linux系统下的网络通信
        套接字:一次通信对象的抽象

2.流程  

发送端流程:1.创建套接字
               2.发送信息
               3.关闭套接字

    接收端流程: 1.创建套接字       
                2.绑定IP和Port
                3.接收信息 
                4.关闭套接字

3.函数接口

(1) socket

socket 
      int socket(int domain, int type, int protocol);
      功能:
        创建套接字
      参数:
        domain: AF_INET 表示IPV4协议
        type:套接字类型
            SOCK_STREAM:流式套接字
            SOCK_DGRAM:数据报套接字
            SOCK_RAW:原始套接字
        protocol:
            TCP和UDP协议:0
      返回值:  
        成功返回用来通信的文件描述符
        失败返回-1 
 

 (2)sendto 

sendto 
      ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
                      const struct sockaddr *dest_addr, socklen_t addrlen);
      功能:
        发送信息
      参数:
        sockfd:套接字文件描述符
        buf:发送数据空间首地址
        len:发送数据长度
        flags:发送属性 默认为0 
        dest_addr:目标地址存放空间首地址
        addrlen:目的地址的长度

struct sockaddr_in {
            sa_family_t    sin_family; /* address family: AF_INET */
            in_port_t      sin_port;   /* port in network byte order */
            struct in_addr sin_addr;   /* internet address */
        };

        /* Internet address. */
        struct in_addr {
            uint32_t       s_addr;     /* address in network byte order */
        };

      返回值:
        成功返回发送字节数
        失败返回-1 

  如果sendto对应的套接字没有绑定端口,则sendto绑定一个随机端口完成发送功能

(3) inet_addr

inet_addr
      in_addr_t inet_addr(const char *cp);
      功能:
        将字符串的IP地址转换为32位的地址类型

(4) htons 

htons 
      uint16_t htons(uint16_t hostshort);
      功能:    
        将本地字节序(小端)转换成网络大端字节序
 

(5) bind 

bind 
      int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
      功能:
        将套接字与IP地址和端口进行绑定
      参数:
        addr:绑定地址结构体空间首地址
        addrlen:绑定地址空间大小
      返回值:
        成功返回0 
        失败返回-1 
      注意:
        只能绑定自己的IP地址

(6)recvfrom 

 ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                        struct sockaddr *src_addr, socklen_t *addrlen);
      功能:
        接收信息
      参数:
        sockfd:套接字文件描述符
        buf:接收数据空间首地址
        len:接收数据长度
        flags:接收的属性 默认为0 
        src_addr:存放发送方地址空间的地址
        addrlen: 要接收的发送方地址的长度
      返回值:
        成功返回实际接收字节数
        失败返回-1 

 练习一:

主机作为发送端

#include "../head.h"
//主机作为发送方
int main()
{int sockfd=0;ssize_t nsize=0;struct sockaddr_in recvaddr;struct sockaddr_in sendaddr;//创建用来通信的套接字sockfd=socket(AF_INET,SOCK_DGRAM,0);//AF_INET:IPV4协议族,SOCK_DGRAM:UDP数据报套接字if(sockfd==-1){perror("failed to socket");return -1;}//将发送端套接字与IP地址和端口号绑定sendaddr.sin_family=AF_INET;sendaddr.sin_port=htons(30000);sendaddr.sin_addr.s_addr=inet_addr("192.168.0.185");bind(sockfd,(struct sockaddr *)&sendaddr,sizeof(sendaddr));//为目的地址赋值recvaddr.sin_family=AF_INET;//协议族为IPV4recvaddr.sin_port=htons(8080);//端口号( htons() 将本地字节序(小端)转换为网络字节序(大端))(发送给wltszs4.3.29网络调试助手)recvaddr.sin_addr.s_addr=inet_addr("192.168.0.135");//IP地址( inet_addr() 将字符串类型转换为二进制地址类型)//向目的地址发送数据nsize=sendto(sockfd,"66666666666",12,0,(struct sockaddr *)&recvaddr,sizeof(recvaddr));//注意强制类型转换if(nsize==-1){perror("failed to sendto");return 0;}printf("发送成功\n");//关闭套接字close(sockfd);return 0;
}

主机作为接收端

#include "../head.h"
int main()
{int sockfd=0;int ret=0;char tmpbuff[200]={0};ssize_t nsize=0;struct sockaddr_in recvaddr;//创建套接字sockfd=socket(AF_INET,SOCK_DGRAM,0);if(sockfd==-1){perror("failed to socket");return -1;}//将套接字和IP地址与端口号绑定recvaddr.sin_family=AF_INET;recvaddr.sin_port=htons(20000);recvaddr.sin_addr.s_addr=inet_addr("192.168.0.185");ret=bind(sockfd,(struct sockaddr *)&recvaddr,sizeof(recvaddr));if(ret==-1){perror("failed to bind");return 0;}//接受数据nsize=recvfrom(sockfd,tmpbuff,sizeof(tmpbuff),0,NULL,NULL);if(nsize==-1){perror("failed to recvfrom");return 0;}//打印数据printf("接收到字节数:%ld,内容为:%s\n",nsize,tmpbuff);//关闭套接字close(sockfd);return 0;
}

练习二:利用UDP编程发送文件

发送端send.c

#include "../head.h"
int main()
{int sockfd;int ret=0;FILE *fp=NULL;struct sockaddr_in recvaddr;char readbuff[1024]={0};size_t size=0;ssize_t nsize=0;//创建套接字sockfd=socket(AF_INET,SOCK_DGRAM,0);if(sockfd==-1){perror("failed to socket");return -1;}//为目的地址赋值recvaddr.sin_family=AF_INET;recvaddr.sin_port=htons(30000);recvaddr.sin_addr.s_addr=inet_addr("192.168.0.187");//输入要发送的文件名printf("请输入要发送的文件名:");fgets(readbuff,sizeof(readbuff),stdin);readbuff[strlen(readbuff)-1]='\0';//打开该文件fp=fopen(readbuff,"r");if(fp==NULL){perror("failed to fopen send.txt");return -1;}//发送文件名nsize=sendto(sockfd,readbuff,strlen(readbuff)+1,0,(struct sockaddr *)&recvaddr,sizeof(recvaddr));if(nsize==-1){perror("failed to sendto");return -1;}
//发送文件内容
while(1)
{size=fread(readbuff,1,sizeof(readbuff),fp);if(size<=0){break;}nsize=sendto(sockfd,readbuff,size,0,(struct sockaddr *)&recvaddr,sizeof(recvaddr));if(nsize==-1){perror("failed to sendto");return -1;}
}
//发送文件结尾关闭标志sprintf(readbuff,".quit");nsize=sendto(sockfd,readbuff,size,0,(struct sockaddr *)&recvaddr,sizeof(recvaddr));if(nsize==-1){perror("failed to sendto");return -1;}//关闭套接字和文件close(sockfd);fclose(fp);return 0;  }

接收文件端

#include "../head.h"
int main()
{int sockfd;int ret=0;FILE *fp=NULL;char filename[100]={0};char tmpbuff[1024]={0};struct sockaddr_in recvaddr;char readbuff[1024]={0};size_t size=0;ssize_t nsize=0;//创建套接字sockfd=socket(AF_INET,SOCK_DGRAM,0);if(sockfd==-1){perror("failed to socket");return -1;}//绑定接收IP地址和套接字,端口号recvaddr.sin_family=AF_INET;recvaddr.sin_port=htons(30000);recvaddr.sin_addr.s_addr=inet_addr("192.168.0.187");bind(sockfd,(struct sockaddr *)&recvaddr,sizeof(recvaddr));//接收文件名nsize=recvfrom(sockfd,filename,sizeof(filename),0,NULL,NULL);if(nsize==-1){perror("failed to recvfrom");return -1;}//创建文件fp=fopen(filename,"w");if(fp==NULL){perror("failed to fopen");return -1;}//接收文件内容while (1){nsize=recvfrom(sockfd,tmpbuff,sizeof(tmpbuff),0,NULL,NULL);if(nsize==0){break;}if(!strcmp(tmpbuff,".quit")){break;}fwrite(tmpbuff,nsize,1,fp);}//关闭套接字和文件close(sockfd);fclose(fp);return 0;  }

练习三:利用UDP编程实现聊天功能

1.(进程实现)

send.c

#include "../head.h"
int main()
{pid_t pid;struct sockaddr_in sendaddr;struct sockaddr_in recvaddr;char tmpbuff[100]={0};ssize_t size_send;ssize_t size_recv;int sockfd=0;sockfd=socket(AF_INET,SOCK_DGRAM,0);if(sockfd==-1){perror("failed to socket");return -1;}recvaddr.sin_family=AF_INET;recvaddr.sin_port=htons(30000);recvaddr.sin_addr.s_addr=inet_addr("192.168.0.187");//第一次发送是为了建立连接,数据可随机发送,不打印size_send = sendto(sockfd,"hello",6,0,(struct sockaddr *)&recvaddr,sizeof(recvaddr));if(size_send==-1){perror("failed to sendto");return -1;}pid=fork();if(pid==-1){perror("failed to fork");return -1;}if(pid==0){   while (1){memset(tmpbuff,0,sizeof(tmpbuff));fgets(tmpbuff,sizeof(tmpbuff),stdin);tmpbuff[strlen(tmpbuff)-1]='\0';size_send=sendto(sockfd,tmpbuff,strlen(tmpbuff),0,(struct sockaddr *)&recvaddr,sizeof(recvaddr));if(size_send==-1){perror("failed to sendto");return -1;}if(!strcmp(tmpbuff,".quit")){break;}}kill(getppid(),SIGKILL);}else if(pid>0){while(1){memset(tmpbuff,0,sizeof(tmpbuff));size_recv = recvfrom(sockfd,tmpbuff,sizeof(tmpbuff),0,NULL,NULL);if(size_recv==-1){perror("failed to recvfrom");return -1;}if(!strcmp(tmpbuff,".quit")){break;}printf("RECV:%s\n",tmpbuff);}kill(pid,SIGKILL);}close(sockfd);return 0;}

recv.c

#include "../head.h"
int main()
{pid_t pid;struct sockaddr_in sendaddr;struct sockaddr_in recvaddr;size_t size_send;size_t size_recv;char tmpbuff[100]={0};socklen_t addrlen=sizeof(sendaddr);int ret=0;int sockfd=0;sockfd=socket(AF_INET,SOCK_DGRAM,0);if(sockfd==-1){perror("failed to socket");return -1;}recvaddr.sin_family=AF_INET;recvaddr.sin_port=htons(30000);recvaddr.sin_addr.s_addr=inet_addr("192.168.0.187");ret=bind(sockfd,(struct sockaddr *)&recvaddr,sizeof(recvaddr));if(ret==-1){perror("failed to bind");return -1;}
//第一次接收是为了建立连接,数据不打印size_recv = recvfrom(sockfd,tmpbuff,sizeof(tmpbuff),0,(struct sockaddr *)&sendaddr,&addrlen);if(size_recv==-1){perror("failed to recvfrom");return -1;}pid=fork();if(pid==-1){perror("failed to fork");return -1;}if(pid==0){while(1){memset(tmpbuff,0,sizeof(tmpbuff));size_recv = recvfrom(sockfd,tmpbuff,sizeof(tmpbuff),0,NULL,NULL);if(size_recv==-1){perror("failed to sendto");return -1;}if(!strcmp(tmpbuff,".quit")){break;}printf("RECV:%s\n",tmpbuff);}kill(getppid(),SIGKILL);}else if(pid>0){while (1){memset(tmpbuff,0,sizeof(tmpbuff));fgets(tmpbuff,sizeof(tmpbuff),stdin);tmpbuff[strlen(tmpbuff)-1]='\0';size_send=sendto(sockfd,tmpbuff,strlen(tmpbuff),0,(struct sockaddr *)&sendaddr,sizeof(sendaddr));if(size_send==-1){perror("failed to sendto");return -1;}if(!strcmp(tmpbuff,".quit")){break;}}kill(pid,SIGKILL);}close(sockfd);return 0;}

2.(线程实现)

send.c

#include "../head.h"int sockfd = 0;
pthread_t tid1;
pthread_t tid2;
struct sockaddr_in recvaddr;void *thread1(void *arg)
{char tmpbuff[1024] = {0};ssize_t nsize = 0;while (1){memset(tmpbuff, 0, sizeof(tmpbuff));fgets(tmpbuff, sizeof(tmpbuff), stdin);tmpbuff[strlen(tmpbuff)-1] = '\0';nsize = sendto(sockfd, tmpbuff, strlen(tmpbuff), 0, (struct sockaddr *)&recvaddr, sizeof(recvaddr));if (-1 == nsize){perror("fail to sendto");return NULL;}if (!strcmp(tmpbuff, ".quit")){break;}}pthread_cancel(tid2);return NULL;
}void *thread2(void *arg)
{  char tmpbuff[1024] = {0};ssize_t nsize = 0;while (1){memset(tmpbuff, 0, sizeof(tmpbuff));nsize = recvfrom(sockfd, tmpbuff, sizeof(tmpbuff), 0, NULL, NULL);if (-1 == nsize){perror("fail to recvfrom");return NULL;}if (!strcmp(tmpbuff, ".quit")){break;}printf("RECV:%s\n", tmpbuff);}pthread_cancel(tid1);return NULL;
}int main(void)
{//1.创建套接字char tmpbuff[1024] = {"hello"};ssize_t nsize = 0;recvaddr.sin_family = AF_INET;recvaddr.sin_port = htons(RECV_PORT);recvaddr.sin_addr.s_addr = inet_addr(RECV_IP);sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (-1 == sockfd){perror("fail to socket");return -1;}//2.发送一次nsize = sendto(sockfd, tmpbuff, strlen(tmpbuff), 0, (struct sockaddr *)&recvaddr, sizeof(recvaddr));if (-1 == nsize){perror("fail to sendto");return -1;}//3.创建两个线程pthread_create(&tid1, NULL, thread1, NULL);pthread_create(&tid2, NULL, thread2, NULL);pthread_join(tid1, NULL);pthread_join(tid2, NULL);close(sockfd);return 0;
}

recv.c

#include "../head.h"int sockfd = 0;
pthread_t tid1;
pthread_t tid2;
struct sockaddr_in recvaddr;
struct sockaddr_in sendaddr;void *thread1(void *arg)
{char tmpbuff[1024] = {0};ssize_t nsize = 0;while (1){memset(tmpbuff, 0, sizeof(tmpbuff));fgets(tmpbuff, sizeof(tmpbuff), stdin);tmpbuff[strlen(tmpbuff)-1] = '\0';nsize = sendto(sockfd, tmpbuff, strlen(tmpbuff), 0, (struct sockaddr *)&sendaddr, sizeof(sendaddr));if (-1 == nsize){perror("fail to sendto");return NULL;}if (!strcmp(tmpbuff, ".quit")){break;}}pthread_cancel(tid2);return NULL;
}void *thread2(void *arg)
{  char tmpbuff[1024] = {0};ssize_t nsize = 0;while (1){memset(tmpbuff, 0, sizeof(tmpbuff));nsize = recvfrom(sockfd, tmpbuff, sizeof(tmpbuff), 0, NULL, NULL);if (-1 == nsize){perror("fail to recvfrom");return NULL;}if (!strcmp(tmpbuff, ".quit")){break;}printf("RECV:%s\n", tmpbuff);}pthread_cancel(tid1);return NULL;
}int main(void)
{//1.创建套接字char tmpbuff[1024] = {"hello"};ssize_t nsize = 0;int ret = 0;socklen_t addrlen = sizeof(sendaddr);recvaddr.sin_family = AF_INET;recvaddr.sin_port = htons(RECV_PORT);recvaddr.sin_addr.s_addr = inet_addr(RECV_IP);sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (-1 == sockfd){perror("fail to socket");return -1;}ret = bind(sockfd, (struct sockaddr *)&recvaddr, sizeof(recvaddr));if (-1 == ret){perror("fail to bind");return -1;}//2.接收一次nsize = recvfrom(sockfd, tmpbuff, sizeof(tmpbuff), 0, (struct sockaddr *)&sendaddr, &addrlen);if (-1 == nsize){perror("fail to recvfrom");return -1;}//3.创建两个线程pthread_create(&tid1, NULL, thread1, NULL);pthread_create(&tid2, NULL, thread2, NULL);pthread_join(tid1, NULL);pthread_join(tid2, NULL);close(sockfd);return 0;
}

相关文章:

网络编程:OSI协议,TCP/IP协议,IP地址,UDP编程

目录 国际网络通信协议标准&#xff1a; 1.OSI协议&#xff1a; 2.TCP/IP协议模型&#xff1a; 应用层 &#xff1a; 传输层&#xff1a; 网络层&#xff1a; IPV4协议 IP地址 IP地址的划分&#xff1a; 公有地址 私有地址 MA…...

QtExa001自动包装流水线的框架设计vs2019QT

QtExa001自动包装流水线的框架设计 工程代码&#xff1a; https://download.csdn.net/download/txwtech/89636815https://download.csdn.net/download/txwtech/89636815 主界面&#xff1a; 设置&#xff1a;进行参数配置&#xff0c;保存ini文件 调试&#xff1a;tcp/ip&…...

SpringBoot拦截器的使用介绍

SpringBoot拦截器的使用介绍 本篇文章主要讲的是 SpringBoot 拦截器的使用介绍。 1、定义拦截器 拦截器&#xff1a;所谓拦截器&#xff0c;就是能够在进行某个操作之前拦截请求&#xff0c;如果请求符合条件就允许在往下执行。 定义拦截器的几种方式。 1.1 实现HandleInt…...

Spring Boot应用中的资源分离与高效打包实践

在电商网站项目中&#xff0c;前端资源通常包括HTML、CSS、JavaScript、图片、字体等静态文件&#xff0c;以及Thymeleaf或Freemarker等模板引擎渲染的页面。将这些资源从Spring Boot主应用中分离出来&#xff0c;不仅有利于前后端团队的并行开发&#xff0c;还能提高应用的加载…...

分析 avformat_open_input 数据读取过程

------------------------------------------------------------ author: hjjdebug date: 2024年 08月 13日 星期二 17:31:43 CST descriptor: 分析 avformat_open_input 数据读取过程 ------------------------------------------------------------ avformat_open_input 中读…...

Apache HOP (Hop Orchestration Platform) VS Data Integration (通常被称为 Kettle)

Apache HOP (Hop Orchestration Platform) 和 Data Integration (通常被称为 Kettle) 都是强大的 ETL (Extract, Transform, Load) 工具&#xff0c; 它们都由 Hitachi Vantara 开发和支持。尽管它们有着相似的目标&#xff0c;即帮助用户进行数据集成任务&#xff0c;但它们在…...

如何判断一个dll/exe是32位还是64位

通过记事本判断&#xff08;可判断C或者C#&#xff09; 64位、将dll用记事本打开&#xff0c;可以看到一堆乱码&#xff0c;但是找到乱码行的第一个PE&#xff0c;如果后面是d?则为64位 32位、将dll用记事本打开&#xff0c;可以看到一堆乱码&#xff0c;但是找到乱码行的第…...

加速网页加载,提升用户体验:HTML、JS 和 Vue 项目优化全攻略

在信息爆炸的时代&#xff0c;网页加载速度成为了用户体验的重中之重。试想一下&#xff0c;如果一个页面加载超过 3 秒&#xff0c;你还有耐心等待吗&#xff1f; 为了留住用户&#xff0c;提升转化率&#xff0c;网页优化势在必行&#xff01; 本文将从 HTML、JavaScript 和…...

LVS服务器基础环境配置

环境配置 1 基础服务关闭 setenforce 0 # 临时关闭selinuxvi /etc/sysconfig/selinux # 永久关闭selinuxsystemctl disable --now firewalld # 关闭防火墙systemctl disable --now NetworkManager # 关闭网络管理器2 centos7软件仓库的配置 mount /dev/cdrom /media以防万一&…...

【Python OpenCV】使用OpenCV实现两张图片拼接

问题引入&#xff1a; 如何使用Python OpenCV实现两张图片的水平拼接和垂直拼接 代码实现&#xff1a; import cv2 import numpy as npdef image_hstack(image_path_1, image_path_2):"""两张图片左右拼接"""img1 cv2.imread(image_path_1)img…...

springboot jar -jar centos后台运行的几种方式

在CentOS系统中&#xff0c;如果你想要在后台运行一个Spring Boot应用程序&#xff0c;你可以使用nohup命令或者使用screen会话。以下是两种常用的方法&#xff1a; 1. **使用nohup命令**&#xff1a; nohup命令可以使进程在你退出SSH会话后继续运行。它还会把标准输出和标…...

【GitLab】使用 Docker 安装 GitLab:配置 SSH 端口

使用 Docker 安装 GitLab 要求修改ssh端口 GitLab 使用 SSH 通过 SSH 与 Git 交互。默认情况下,GitLab 使用端口22。 要在使用 GitLab Docker 映像时使用其他端口,您可以执行以下操作之一: 更改服务器的 SSH 端口(推荐)。 更改 GitLab Shell SSH 端口。 更改服务器的 SSH …...

【pdf文件生成】如何将盖章的文件生成PDF文件

一、提出问题 在我们的工作中&#xff0c;有时候上级让下级将盖章的文件生成PDF文件通过内部平台发送到上级邮箱&#xff0c;那如何解决呢&#xff1f;是去找一个扫描仪&#xff0c;还是用手机拍图转。用Python基实就能实现。 二、分析问题 现在网上好多的软件都是收费的&am…...

铝壳电阻在电路中的作用和影响是什么?

铝壳电阻&#xff0c;顾名思义&#xff0c;就是用铝材料制成的电阻。在电路中&#xff0c;它主要起到限流、分压、负载等作用。下面详细介绍铝壳电阻在电路中的作用和影响。 1. 限流作用&#xff1a;铝壳电阻可以限制电流的大小&#xff0c;防止电流过大而损坏电路。当电路中的…...

# Python 判断入参日期是周几

在数据分析和软件开发中&#xff0c;经常需要判断某个特定日期是星期几。Python 提供了强大的日期时间处理功能&#xff0c;可以轻松实现这一功能。本篇文章将介绍如何使用 Python 的内置库来判断给定日期是星期几&#xff0c;并提供具体实例。 1. 使用 datetime 模块 Python…...

井字棋游戏(HTML+CSS+JavaScript)

&#x1f30f;个人博客主页&#xff1a;心.c 前言&#xff1a;这两天在写植物大战僵尸&#xff0c;写不动了&#xff0c;现在和大家分享一下之前我写的一个很简单的小游戏井字棋&#xff0c;这个没有AI&#xff0c;可以两个人一起玩&#xff0c;如果大家觉得我哪里写的有一些问…...

HTML 列表和容器元素——WEB开发系列10

HTML 提供了多种方式来组织和展示内容&#xff0c;其中包括无序列表、有序列表、分区元素 ​​<div>​​ 和内联元素 ​​<span>​​、以及如何使用 ​​<div>​​​ 进行布局和表格布局。 一、HTML 列表 1. 无序列表 (​​<ul>​​) 无序列表用于展…...

Java数组的高级使用技巧与性能优化

Java数组的高级使用技巧与性能优化 大家好&#xff0c;我是微赚淘客返利系统3.0的小编&#xff0c;是个冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; Java数组是程序设计中的基础数据结构&#xff0c;提供了一种存储固定大小的同类型元素的方式。本文将介绍Jav…...

python spyne报No module named ‘http.cookies‘的解决

python spyne报No module named ‘http.cookies’ python实现webservice服务端时&#xff0c;会使用spyne这个库&#xff0c;安装后&#xff0c;运行会提示No module named ‘http.cookies’。 尝试过不行的方法 pip install http.cookiespip install http.cookiejar 可行的…...

vmware虚拟机玩GPU显卡直通

安装好exsi以后&#xff0c;找到管理----硬件-----PCI设备&#xff0c;勾选想要直通的显卡&#xff0c;然后点击“切换直通” 切换以后可以看到列表中的直通列显示为活动就对了。 然后编辑虚拟机设置&#xff0c;CPU关闭硬件虚拟化&#xff08;向客户机操作系统公开硬件辅助的…...

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站&#xff0c;会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后&#xff0c;网站没有变化的情况。 不熟悉siteground主机的新手&#xff0c;遇到这个问题&#xff0c;就很抓狂&#xff0c;明明是哪都没操作错误&#x…...

idea大量爆红问题解决

问题描述 在学习和工作中&#xff0c;idea是程序员不可缺少的一个工具&#xff0c;但是突然在有些时候就会出现大量爆红的问题&#xff0c;发现无法跳转&#xff0c;无论是关机重启或者是替换root都无法解决 就是如上所展示的问题&#xff0c;但是程序依然可以启动。 问题解决…...

如何在看板中体现优先级变化

在看板中有效体现优先级变化的关键措施包括&#xff1a;采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中&#xff0c;设置任务排序规则尤其重要&#xff0c;因为它让看板视觉上直观地体…...

linux 错误码总结

1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

【论文笔记】若干矿井粉尘检测算法概述

总的来说&#xff0c;传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度&#xff0c;通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等

&#x1f50d; 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术&#xff0c;可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势&#xff0c;还能有效评价重大生态工程…...

使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度

文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

C++使用 new 来创建动态数组

问题&#xff1a; 不能使用变量定义数组大小 原因&#xff1a; 这是因为数组在内存中是连续存储的&#xff0c;编译器需要在编译阶段就确定数组的大小&#xff0c;以便正确地分配内存空间。如果允许使用变量来定义数组的大小&#xff0c;那么编译器就无法在编译时确定数组的大…...

在Ubuntu24上采用Wine打开SourceInsight

1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...