httpserver 下载服务器demo 以及libevent版本的 httpserver

实现效果如下:

图片可以直接显示 

cpp h 这些可以直接显示 其他的 则是提示是否要下载

单线程 还有bug

代码如下  先放上来 

#include "httpserver.h"
#include "stdio.h"
#include <stdlib.h>
#include <arpa/inet.h>
#include <sys/epoll.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/sendfile.h>
#include <dirent.h>#define BURSIZE 1024
int hex2dec(char c)
{if ('0' <= c && c <= '9') {return c - '0';} else if ('a' <= c && c <= 'f') {return c - 'a' + 10;} else if ('A' <= c && c <= 'F') {return c - 'A' + 10;} else {return -1;}
}char dec2hex(short int c)
{if (0 <= c && c <= 9) {return c + '0';} else if (10 <= c && c <= 15) {return c + 'A' - 10;} else {return -1;}
}/** 编码一个url*/
void urlencode(char url[])
{int i = 0;int len = strlen(url);int res_len = 0;char res[BURSIZE];for (i = 0; i < len; ++i) {char c = url[i];if (('0' <= c && c <= '9') ||('a' <= c && c <= 'z') ||('A' <= c && c <= 'Z') || c == '/' || c == '.') {res[res_len++] = c;} else {int j = (short int)c;if (j < 0)j += 256;int i1, i0;i1 = j / 16;i0 = j - i1 * 16;res[res_len++] = '%';res[res_len++] = dec2hex(i1);res[res_len++] = dec2hex(i0);}}res[res_len] = '\0';strcpy(url, res);
}/** 解码url*/
void urldecode(char url[])
{int i = 0;int len = strlen(url);int res_len = 0;char res[BURSIZE];for (i = 0; i < len; ++i) {char c = url[i];if (c != '%') {res[res_len++] = c;} else {char c1 = url[++i];char c0 = url[++i];int num = 0;num = hex2dec(c1) * 16 + hex2dec(c0);res[res_len++] = num;}}res[res_len] = '\0';strcpy(url, res);
}int CreateSocketFD()
{int fd = 0;fd = socket(AF_INET,SOCK_STREAM,0);if(fd == -1){perror("Scoket fd = -1");return 0;}int reuseport = 1;int ret = setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&reuseport,sizeof(reuseport));if(ret == -1){perror("setsocketopt failed");return -1;}struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(8888);addr.sin_addr.s_addr = INADDR_ANY;ret = bind(fd,(struct sockaddr*)&addr,sizeof(addr));if(ret == -1){perror("bind error");return -1;}ret = listen(fd,10);if(ret == -1){perror("listen error ");return -1;}return fd;
}int AcceptClients(int epoll_fd,int fd)
{struct sockaddr addr;int cfd = accept(fd,NULL,NULL);if(cfd == -1){perror("accept failed");}int flag = fcntl(cfd,F_GETFL);flag |= O_NONBLOCK;fcntl(cfd,F_SETFL,flag);struct epoll_event ev;ev.data.fd = cfd;ev.events = EPOLLIN|EPOLLET;int ret = epoll_ctl(epoll_fd,EPOLL_CTL_ADD,cfd,&ev);if(ret == -1){perror("epoll ctl failed");return 0;}return 0;
}const char *GetFileType(const char *filename)
{const char *dot = strrchr(filename,'.');if(dot == NULL){return "text/plain; charset=utf-8";}if(strcmp(dot,".jpg") == 0 ||strcmp(dot,".jpeg") == 0){return "image/jpg";}if(strcmp(dot,".html") == 0 ||strcmp(dot,".htm") == 0){return "text/html; charset=utf-8";}    if(strcmp(dot,".png") == 0){return "image/png";}    if(strcmp(dot,".bmp") == 0){return "image/bmp";}        if(strcmp(dot,".gif") == 0){return "image/gif";}            if(strcmp(dot,".css") == 0){return "text/css";}           if(strcmp(dot,".mp3") == 0){return "audio/mpeg";}               return "text/plain; charset=utf-8";
}int SendHead(int cfd,int status ,const char *desc,const char *type,int size)
{char buf[4096] = {0};sprintf(buf,"http/1.1 %d %s\r\n",status,desc);sprintf(buf+strlen(buf),"content-type: %s\r\n",type);sprintf(buf+strlen(buf),"content-length: %d\r\n\r\n",size);    printf("SendHead buf[%s]\n",buf);send(cfd,buf,strlen(buf),0);return 0;
}int SendDir(const char *dirname,int cfd)
{char buf[4096] = {0};sprintf(buf,"<html><head><title>%s</title></head><body><table>",dirname);printf("SendDir dirname=[%s]\n",dirname);struct dirent **namelist;int count = scandir(dirname,&namelist,NULL,alphasort);printf("SendDir count=[%d]\n",count);for(int i = 0;i< count;i++){char *name = namelist[i]->d_name;struct stat st;char sub_path[1024]={0};sprintf(sub_path,"%s/%s",dirname,name);stat(sub_path,&st);if(S_ISDIR(st.st_mode)){sprintf(buf+strlen(buf),"<tr><td><a href=\"%s/\">%s</a></td><td>%ld</td></tr>",name,name,st.st_size);}else{sprintf(buf+strlen(buf),"<tr><td><a href=\"%s\">%s</a></td><td>%ld</td></tr>",name,name,st.st_size);}printf("cfd:%d Sendbuf[%s]\n",cfd,buf);send(cfd,buf,strlen(buf),0);memset(buf,0,sizeof(buf));free(namelist[i]);}sprintf(buf,"</table></body></html>");printf("cfd:%d Sendbuf[%s]\n",cfd,buf);send(cfd,buf,strlen(buf),0);free(namelist);return 0;
}int SendFile(const char* filename,int cfd)
{int fd = open(filename,O_RDONLY);if(fd >0){#if 0while(1){char buf[1024];int len = read(fd,buf,sizeof buf);if(len >0){send(cfd,buf,len,0);usleep(10);}else if(len == 0){printf("Read file end\n");break;}else{perror("read error");}}#elseoff_t offset = 0;int file_size = lseek(fd,0,SEEK_END);lseek(fd,0,SEEK_SET);while(offset <file_size){int send_len = sendfile(cfd,fd,&offset,file_size-offset);if(send_len == -1){if(errno == EAGAIN){//perror("sendfile no data send");}else{perror("sendfile ret -1");}}else{printf("Send len:%d\n",send_len);}}#endif}else{perror("open file failed");}close(fd);return 0;
}int ParseReqLine(const char *line,int cfd)
{char method[12];char path[1024];printf("ParseReqLine=[%s]\n",line);int ret = sscanf(line,"%[^ ] %[^ ]",method,path);printf("sscanf ret = %d\n",ret);printf("method=[%s],path=[%s]\n",method,path);urldecode(path);printf("afterdecode path=[%s]\n",path);if(ret ==2 ){}else{printf("Reqest line parse failed\n");return -1;}if(strcasecmp(method,"get") == 0){}else if(strcasecmp(method,"post")==0){}else{return -1;}char *file = NULL;if(strcmp(path,"/") == 0){   file = "./";}else{file = path+1;}struct stat st;ret = stat(file,&st);if(ret == -1){printf("file doest not exist\n");SendHead(cfd,404,"Not found",GetFileType(".html"),-1);SendFile("404.html",cfd);return -1;}if(S_ISDIR(st.st_mode)){printf("Directory\n");SendHead(cfd,200,"OK",GetFileType(".html"),-1);SendDir(file,cfd);}else{printf("File\n");SendHead(cfd,200,"OK",GetFileType(file),st.st_size);SendFile(file,cfd);}return 0;
}int Request(int epoll_fd,int cfd)
{char buffer[4096] = {0};char temp_buf[1024] = {0};int read_len = 0;int total = 0;while((read_len = recv(cfd,temp_buf,sizeof(temp_buf),0))>0){if(total+read_len <sizeof(buffer)){memcpy(buffer+total,temp_buf,read_len);total+=read_len;}}if(read_len == -1 && errno == EAGAIN){//读取数据结束char *p = strstr(buffer,"\r\n");if(p){int len = p - buffer;buffer[len] = 0;ParseReqLine(buffer,cfd);}}else if(read_len == 0){//Client close socketepoll_ctl(epoll_fd,EPOLL_CTL_DEL,cfd,NULL);close(cfd);}else{perror("recv error");}return 0;
}int EPOLL_Run(int server_fd)
{int epoll_fd = epoll_create(10);if(epoll_fd == -1){perror("epoll_create failed");return 0;}struct epoll_event ev;ev.data.fd = server_fd;ev.events = EPOLLIN;int ret = epoll_ctl(epoll_fd,EPOLL_CTL_ADD,server_fd,&ev);if(ret == -1){perror("epoll_ctl failed");return 0;}struct epoll_event events[512];while(true){int nReady = epoll_wait(epoll_fd,events,512,-1);for(int i = 0;i<nReady;i++){int fd = events[i].data.fd;if(fd == server_fd){AcceptClients(epoll_fd,fd);}else{if(events[i].events &EPOLLOUT){//g_writeable = true;printf("客户端可以写数据了");}if(events[i].events &EPOLLIN){Request(epoll_fd,fd);}}}}return epoll_fd;
}
int main()
{printf("Hello world\n");char work_dir[] = "/home/develop/httpserver";//chdir(work_dir);int server_fd = CreateSocketFD();if(server_fd <=0){return 0;}EPOLL_Run(server_fd);close(server_fd);return 0;
}

以上  如果遇到大文件 比如mp3 文件的话  就没办法 预览  试听 下载大文件也有问题  

跟踪发现是SendFile 那里有问题   会返回-1

根据网上的例子 改了一个 基于libevent版本的  不会存在这个问题 

#include "sushi.h"
#include "stdio.h"#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/epoll.h>
#include <signal.h>#include <fcntl.h>
#include <unordered_map>
#include <memory>
#include <vector>#include <arpa/inet.h>
#include <sys/epoll.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/sendfile.h>#include <dirent.h>#include <evhttp.h>
#include <event.h>
#include <string.h>
#include "event2/http.h"
#include "event2/event.h"
#include "event2/buffer.h"
#include "event2/bufferevent.h"
#include "event2/bufferevent_compat.h"
#include "event2/http_struct.h"
#include "event2/http_compat.h"
#include "event2/util.h"
#include "event2/listener.h"
#include "event2/thread.h"#define MAX_EVENTS	100	
#define RECVBUFSIZ	20bool g_run_flag = true;void sig_handler(int signo)
{g_run_flag = false;printf("\033[0;31mprogram exit by user cmd !!!!\033[0;39m\n");
}#define BURSIZE 1024
int hex2dec(char c)
{if ('0' <= c && c <= '9') {return c - '0';} else if ('a' <= c && c <= 'f') {return c - 'a' + 10;} else if ('A' <= c && c <= 'F') {return c - 'A' + 10;} else {return -1;}
}char dec2hex(short int c)
{if (0 <= c && c <= 9) {return c + '0';} else if (10 <= c && c <= 15) {return c + 'A' - 10;} else {return -1;}
}/** 编码一个url*/
void urlencode(char url[])
{int i = 0;int len = strlen(url);int res_len = 0;char res[BURSIZE];for (i = 0; i < len; ++i) {char c = url[i];if (('0' <= c && c <= '9') ||('a' <= c && c <= 'z') ||('A' <= c && c <= 'Z') || c == '/' || c == '.') {res[res_len++] = c;} else {int j = (short int)c;if (j < 0)j += 256;int i1, i0;i1 = j / 16;i0 = j - i1 * 16;res[res_len++] = '%';res[res_len++] = dec2hex(i1);res[res_len++] = dec2hex(i0);}}res[res_len] = '\0';strcpy(url, res);
}/** 解码url*/
void urldecode(char url[])
{int i = 0;int len = strlen(url);int res_len = 0;char res[BURSIZE];for (i = 0; i < len; ++i) {char c = url[i];if (c != '%') {res[res_len++] = c;} else {char c1 = url[++i];char c0 = url[++i];int num = 0;num = hex2dec(c1) * 16 + hex2dec(c0);res[res_len++] = num;}}res[res_len] = '\0';strcpy(url, res);
}const char *GetFileType(const char *filename)
{const char *dot = strrchr(filename,'.');if(dot == NULL){return "text/plain; charset=utf-8";}if(strcmp(dot,".jpg") == 0 ||strcmp(dot,".jpeg") == 0){return "image/jpg";}if(strcmp(dot,".html") == 0 ||strcmp(dot,".htm") == 0){return "text/html; charset=utf-8";}    if(strcmp(dot,".png") == 0){return "image/png";}    if(strcmp(dot,".bmp") == 0){return "image/bmp";}        if(strcmp(dot,".gif") == 0){return "image/gif";}            if(strcmp(dot,".css") == 0){return "text/css";}           if(strcmp(dot,".mp3") == 0){return "audio/mpeg";}               return "text/plain; charset=utf-8";
}int SendHead(struct bufferevent *event,int status ,const char *desc,const char *type,int size)
{char buf[4096] = {0};sprintf(buf,"http/1.1 %d %s\r\n",status,desc);sprintf(buf+strlen(buf),"content-type: %s\r\n",type);sprintf(buf+strlen(buf),"content-length: %d\r\n\r\n",size);    printf("SendHead buf[%s]\n",buf);//send(cfd,buf,strlen(buf),0);bufferevent_write(event,buf,strlen(buf));return 0;
}int SendDir(struct bufferevent *event,const char *dirname)
{char buf[4096] = {0};sprintf(buf,"<html><head><title>%s</title></head><body><table>",dirname);printf("SendDir dirname=[%s]\n",dirname);struct dirent **namelist;int count = scandir(dirname,&namelist,NULL,alphasort);printf("SendDir count=[%d]\n",count);for(int i = 0;i< count;i++){char *name = namelist[i]->d_name;struct stat st;char sub_path[1024]={0};sprintf(sub_path,"%s/%s",dirname,name);stat(sub_path,&st);if(S_ISDIR(st.st_mode)){sprintf(buf+strlen(buf),"<tr><td><a href=\"%s/\">%s</a></td><td>%ld</td></tr>",name,name,st.st_size);}else{sprintf(buf+strlen(buf),"<tr><td><a href=\"%s\">%s</a></td><td>%ld</td></tr>",name,name,st.st_size);}//printf("cfd:%d Sendbuf[%s]\n",cfd,buf);//send(cfd,buf,strlen(buf),0);bufferevent_write(event,buf,strlen(buf));    memset(buf,0,sizeof(buf));free(namelist[i]);}sprintf(buf,"</table></body></html>");//printf("cfd:%d Sendbuf[%s]\n",cfd,buf);//send(cfd,buf,strlen(buf),0);bufferevent_write(event,buf,strlen(buf));    	free(namelist);return 0;
}int SendFile(struct bufferevent *event,const char* filename)
{int fd = open(filename,O_RDONLY);if(fd >0){#if 1while(1){char buf[1024];int len = read(fd,buf,sizeof buf);if(len >0){//send(cfd,buf,len,0);bufferevent_write(event,buf,len);    usleep(10);}else if(len == 0){printf("Read file end\n");break;}else{perror("read error");}}#elseoff_t offset = 0;int file_size = lseek(fd,0,SEEK_END);lseek(fd,0,SEEK_SET);while(offset <file_size){int send_len = sendfile(cfd,fd,&offset,file_size-offset);if(send_len == -1){if(errno == EAGAIN){//perror("sendfile no data send");}else{perror("sendfile ret -1");}}else{printf("Send len:%d\n",send_len);}}#endif}else{perror("open file failed");}close(fd);return 0;
}int http_request(struct bufferevent *event,char *path)
{char *file = NULL;if(strcmp(path,"/") == 0){   file = "./";}else{file = path+1;}struct stat st;int ret = stat(file,&st);if(ret == -1){printf("file doest not exist\n");SendHead(event,404,"Not found",GetFileType(".html"),-1);SendFile(event,"404.html");return -1;}if(S_ISDIR(st.st_mode)){printf("Directory\n");SendHead(event,200,"OK",GetFileType(".html"),-1);SendDir(event,file);}else{printf("File\n");SendHead(event,200,"OK",GetFileType(file),st.st_size);SendFile(event,file);}return 0;
}void read_cb(struct bufferevent *event,void *arg)
{char buf[256] = {0};char method[10]= {0},path[256]={0},protocol[10]={0};int ret = bufferevent_read(event,buf,sizeof(buf));if(ret >0){sscanf(buf,"%[^ ] %[^ ] %[^ \r\n]",method,path,protocol);if(strcasecmp(method,"get") == 0){char bufline[256] = {0};write(STDOUT_FILENO,buf,ret);while((ret = bufferevent_read(event,bufline,sizeof(bufline)))>0){write(STDOUT_FILENO,bufline,ret);}http_request(event,path);}}
}void bevent_cb(struct bufferevent *event,short what,void *arg)
{if(what & BEV_EVENT_EOF){printf("client closeed\n");bufferevent_free(event);}else if(what & BEV_EVENT_ERROR){printf("client error\n");bufferevent_free(event);}else if(what & BEV_EVENT_CONNECTED){printf("new client connected\n");}
}void listener_cb(struct evconnlistener *listener,evutil_socket_t fd,struct sockaddr *addr,int socklen,void *arg)
{struct event_base *base = (struct event_base*)arg;struct bufferevent *event=  bufferevent_socket_new(base,fd,BEV_OPT_CLOSE_ON_FREE);bufferevent_setcb(event,read_cb,NULL,bevent_cb,base);bufferevent_enable(event,EV_READ|EV_WRITE);
}int main (int argc ,char*argv[])
{signal(SIGINT, sig_handler);signal(SIGTERM, sig_handler);signal(SIGKILL, sig_handler);//Program can not recieve SIGKILL(9) signal so.... this cmd does not make any sense// Ignore broken pipessignal(SIGPIPE, SIG_IGN);char work_dir[256]={0};strcpy(work_dir,getenv("PWD"));printf("dir:%s\n",work_dir);chdir(work_dir);struct event_base *base = event_base_new();struct sockaddr_in server;server.sin_family = AF_INET;server.sin_port = htons(9999);server.sin_addr.s_addr = htonl(INADDR_ANY);struct evconnlistener *listener = evconnlistener_new_bind(base,listener_cb,base,LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE_PORT,-1,(struct sockaddr *)&server,sizeof(server));event_base_dispatch(base);event_base_free(base);evconnlistener_free(listener);printf("Exit normally\n");return 0;
}

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

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

相关文章

录屏软件——Vizard

Vizard&#xff0c;美且实用的网页端录屏软件&#xff0c;轻巧不占内存。Windows/Mac OS均适用。 可以录电脑操作、录软件教程、录网课、录bug、录工作汇报、录创作素材&#xff08;游戏&#xff09;……几乎能想到的一切录屏场景。 除了完全免费的在线录屏&#xff0c;Vizar…

激光雷达中实现F-P标准具高热稳定性的帕尔贴精密温控解决方案

摘要&#xff1a;法布里-珀罗标准具作为一种具有高温度敏感性的精密干涉分光器件&#xff0c;在具体应用中对热稳定性具有很高的要求&#xff0c;如温度波动不能超过0.01℃&#xff0c;为此本文提出了相应的高精度恒温控制解决方案。解决方案具体针对温度控制精度和温度均匀性控…

c++中的动态内存管理

目录 1.内存分布 2.c语言动态内存管理 3.c动态内存管理 4.operator new 与operator delete 函数 5.定位new 6.malloc/free 与 new/delete 的区别 1.内存分布 首先我们需要了解一下数据在内存中的分布&#xff0c;请看以下代码&#xff1a; int globalVar 1; static in…

C#停车场管理系统

目录 一、绪论1.1内容简介及意义1.2开发工具及技术介绍 二、总体设计2.1系统总体架构2.2登录模块总体设计2.3主界面模块总体设计2.4停车证管理模块总体设计2.5停车位管理模块总体设计2.6员工管理模块总体设计2.7其他模块总体设计 三、详细设计3.1登录模块设计3.2主界面模块设计…

想要精通算法和SQL的成长之路 - 并查集的运用和案例(省份数量)

想要精通算法和SQL的成长之路 - 并查集的运用 前言一. 并查集的使用和模板1.1 初始化1.2 find 查找函数1.3 union 合并集合1.4 connected 判断相连性1.5 完整代码 二. 运用案例 - 省份数量 前言 想要精通算法和SQL的成长之路 - 系列导航 一. 并查集的使用和模板 先说一下并查集…

力扣:119. 杨辉三角 II(Python3)

题目&#xff1a; 给定一个非负索引 rowIndex&#xff0c;返回「杨辉三角」的第 rowIndex 行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;力扣&#xff08;LeetCode&#xff09…

计算机竞赛 题目: 基于深度学习的疲劳驾驶检测 深度学习

文章目录 0 前言1 课题背景2 实现目标3 当前市面上疲劳驾驶检测的方法4 相关数据集5 基于头部姿态的驾驶疲劳检测5.1 如何确定疲劳状态5.2 算法步骤5.3 打瞌睡判断 6 基于CNN与SVM的疲劳检测方法6.1 网络结构6.2 疲劳图像分类训练6.3 训练结果 7 最后 0 前言 &#x1f525; 优…

JavaScript:从入门到进阶的旅程

JavaScript是一种广泛使用的编程语言&#xff0c;为网页和应用程序提供了交互性和动态性。从初学者到资深开发者&#xff0c;JavaScript都是一项值得掌握的技能。在本文中&#xff0c;我们将探讨JavaScript的基础知识&#xff0c;以及一些进阶的概念和技巧。 一、JavaScript简…

Spring的注解开发-注解原理解析-xml方式/注解方式组件扫描

目录 Spring注解的解析原理 xml配置组件扫描 注解方式配置组件扫描 原理图 yysy&#xff0c;没有搞太明白&#xff0c;真的复杂&#xff0c;欢迎大佬留言解惑 Spring注解的解析原理 使用Component等注解配置完毕后&#xff0c;要配置组件扫描才能使注解生效 xml配置组件扫…

2023年【高压电工】证考试及高压电工复审模拟考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 高压电工证考试根据新高压电工考试大纲要求&#xff0c;安全生产模拟考试一点通将高压电工模拟考试试题进行汇编&#xff0c;组成一套高压电工全真模拟考试试题&#xff0c;学员可通过高压电工复审模拟考试全真模拟&a…

第 4 章 串(图书关键字索引表实现)

1. 背景说明 需要从书目文件中获取其关键字及对应的书号索引 bookInfo.txt 005 Computer Data Structures 010 Introduction to Data Structures 023 Fundamentals of Data Structures 034 The Design and Analysis of Computer Algorithms 050 Introduction to Numerical Anal…

文件编码格式

一、问题场景 笔者在写controller层出现了一些小问题&#xff1a;测试controller层的一些请求的时候&#xff0c;后端控制台打印的是乱码&#xff0c;网上找了很多说改UTF-8的&#xff0c;但是我去设置里面全部都改为UTF-8了&#xff0c;结果仍然无济于事&#xff0c;甚至还把…

学过的汇编指令整合

1.数据搬移指令 <opcode>{<cond>}{s} <Rd>, <shifter_operand> 解释&#xff1a; <opcode>&#xff1a;指令码 {<cond>}&#xff1a;条件码 {s}&#xff1a;状态位&#xff0c;如果在指令后面加上s&#xff0c;则运算的结果会影响CPSR的条…

2023-09-28 monetdb-databae的概念和作用-分析

摘要: 每个数据库对于db,schema以及user,role都有一套自己的设计, 不同数据库间对于相同名字的东西例如database和schema可以说南辕北辙, 例如mysql中schema其实是database的同义词. 本文分析monetdb的database的概念和作用 database的概念和作用: 和mysql的database完全不同…

Windows11安装MySQL8.1

安装过程中遇到任何问题均可以参考(这个博客只是单纯升级个版本和简化流程) Windows安装MySQL8教程-CSDN博客 到官网下载mysql8数据库软件 MySQL :: Download MySQL Community Server 下载完后,解压到你需要安装的文件夹 其中的配置文件内容了如下 [mysqld]# 设置3306端口po…

云原生微服务 第六章 Spring Cloud Netflix Eureka集成OpenFeign组件,实现微服务的远程调用、负载均衡

系列文章目录 第一章 Java线程池技术应用 第二章 CountDownLatch和Semaphone的应用 第三章 Spring Cloud 简介 第四章 Spring Cloud Netflix 之 Eureka 第五章 Spring Cloud Netflix 之 Ribbon 第六章 Spring Cloud 之 OpenFeign 文章目录 系列文章目录前言1、OpenFeign的实现…

STM32CubeMX学习笔记-USB接口使用(HID按键)

STM32CubeMX学习笔记-USB接口使用&#xff08;HID按键&#xff09; 一、USB简介1.1 USB HID简介 二、新建工程1. 打开 STM32CubeMX 软件&#xff0c;点击“新建工程”2. 选择 MCU 和封装3. 配置时钟4. 配置调试模式 三、USB3.1 参数配置3.2 引脚配置3.3 配置时钟3.4 USB Device…

Transformer学习-self-attention

这里写自定义目录标题 Self-attentionMulti-head self-attention用self-attention解决其他问题 Self-attention 用Wq、Wk、Wv分别乘输入向量得到q、k、v向量 用每个q向量乘所有的k向量得到对应项的attention&#xff0c;即用每项的query向量去匹配所有的key向量&#xff0c;得…

数字IC前端学习笔记:数字乘法器的优化设计(阵列乘法器)

相关阅读 数字IC前端https://blog.csdn.net/weixin_45791458/category_12173698.html?spm1001.2014.3001.5482 数字信号处理作为微处理器的核心部件&#xff0c;是决定着总体处理器性能的因素之一&#xff0c;而数字乘法器是最常见的一种数字信号处理电路。通常情况下&#…

python二次开发CATIA:为选中元素上色

先打开一个零件文档&#xff0c;然后用鼠标选中元素&#xff0c;再运行如下python程序&#xff1a; import win32com.client import pywintypes # 导入pywintypes模块 import random # 启动CATIA应用 catia win32com.client.Dispatch(CATIA.Application) catia.visible1try:…