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

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;
}

相关文章:

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

实现效果如下&#xff1a; 图片可以直接显示 cpp h 这些可以直接显示 其他的 则是提示是否要下载 单线程 还有bug 代码如下 先放上来 #include "httpserver.h" #include "stdio.h" #include <stdlib.h> #include <arpa/inet.h> #include…...

构建强大的RESTful API:@RestController与@Controller的对比与应用

构建强大的RESTful API&#xff1a;RestController与Controller的对比与应用 前言什么是RESTful APIRestController&#xff0c;Controller&#xff0c;ResponseBody1. Controller注解&#xff1a;2. RestController注解&#xff1a;3. ResponseBody注解&#xff1a; 示例非thy…...

【Java-LangChain:使用 ChatGPT API 搭建系统-10】评估(下)-当不存在一个简单的正确答案时

第十章&#xff0c;评估&#xff08;下&#xff09;-当不存在一个简单的正确答案时 在上一章中&#xff0c;了解了如何评估 LLM 模型在 有明确正确答案 的情况下的输出&#xff0c;我们可以编写一个函数来判断 LLM 输出是否正确地分类并列出产品。 然而&#xff0c;如果 LLM …...

【微服务的集成测试】python实现-附ChatGPT解析

1.题目 微服务的集成测试 知识点:深搜 时间限制: 1s 空间限制: 256MB 限定语言:不限 题目描述: 现在有n个容器服务,服务的启动可能有一定的依赖性 (有些服务启动没有依赖)其次服务自身启动加载会消耗一些时间。 给你一个 nxn 的二维矩阵 useTime,其中 useTime[i][i]=10 表示…...

Mesa新版来袭

Mesa 17.1.6 发布了&#xff0c;Mesa 是一个三维&#xff08;3D&#xff09;图形库的开源集合&#xff0c;其主要目标是在 Linux / UNIX 操作系统下实现各种 API&#xff08;应用程序编程接口&#xff09;和 OpenGL 规范。 它面向 3D 计算机图形&#xff0c;硬件加速 3D 渲染和…...

基于 SpringBoot 2.7.x 使用最新的 Elasticsearch Java API Client 之 ElasticsearchClient

1. 从 RestHighLevelClient 到 ElasticsearchClient 从 Java Rest Client 7.15.0 版本开始&#xff0c;Elasticsearch 官方决定将 RestHighLevelClient 标记为废弃的&#xff0c;并推荐使用新的 Java API Client&#xff0c;即 ElasticsearchClient. 为什么要将 RestHighLevelC…...

辅助驾驶功能开发-功能对标篇(15)-NOA领航辅助系统-吉利

1.横向对标参数 厂商吉利车型FX11/EX11/DCY11/G636上市时间2022Q4方案6V5R+1DMS摄像头前视摄像头1*(8M)侧视摄像头/后视摄像头1环视摄像头4DMS摄像头1雷达毫米波雷达54D毫米波雷达/超声波雷达12激光雷达/域控供应商福瑞泰克辅助驾驶软件供应商福瑞泰克高精度地图百度芯片TDA4 T…...

javascript: Sorting Algorithms

// Sorting Algorithms int JavaScript https://www.geeksforgeeks.org/sorting-algorithms/ /** * file Sort.js * 1. Bubble Sort冒泡排序法 * param arry * param nszie */ function BubbleSort(arry, nszie) {var i, j, temp;var swapped;for (i 0; i < nszie - 1; i)…...

嵌入式Linux应用开发-驱动大全-同步与互斥④

嵌入式Linux应用开发-驱动大全-同步与互斥④ 第一章 同步与互斥④1.5 自旋锁spinlock的实现1.5.1 自旋锁的内核结构体1.5.2 spinlock在UP系统中的实现1.5.3 spinlock在SMP系统中的实现 1.6 信号量semaphore的实现1.6.1 semaphore的内核结构体1.6.2 down函数的实现1.6.3 up函数的…...

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

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

C/C++学习 -- 分组密算法(3DES算法)

1. 3DES算法概述 3DES&#xff08;Triple Data Encryption Standard&#xff09;&#xff0c;又称为TDEA&#xff08;Triple Data Encryption Algorithm&#xff09;&#xff0c;是一种对称加密算法&#xff0c;是DES&#xff08;Data Encryption Standard&#xff09;的加强版…...

C/C++面试题总结

1.new与malloc的区别 new操作符从自由存储区上为对象动态分配内存空间&#xff0c;而malloc函数从堆上动态分配内存。 使用new操作符申请内存分配时无须指定内存块的大小&#xff0c;而malloc则需要显式地指出所需内存的尺寸。 int *p new int; delete p;//一定要配对使用n…...

Java下正面解除警告Unchecked cast: ‘java.lang.Object‘ to ‘java.util.ArrayList‘

就是我在反序列化时&#xff0c;遇到这样一个警告&#xff1a; Unchecked cast: java.lang.Object to java.util.ArrayList<com.work1.Student>然后我去网上查&#xff0c;有些人说用SuppressWarnings(“unchecked”)去忽略警告&#xff0c;但是我觉得作为一名合格的程序…...

图像处理与计算机视觉--第四章-图像滤波与增强-第二部分

目录 1.图像噪声化处理与卷积平滑 2.图像傅里叶快速变换处理 3.图像腐蚀和膨胀处理 4 图像灰度调整处理 5.图像抖动处理算法 学习计算机视觉方向的几条经验: 1.学习计算机视觉一定不能操之过急&#xff0c;不然往往事倍功半&#xff01; 2.静下心来&#xff0c;理解每一个…...

[前端基础]typescript安装以及类型拓展

&#xff08;0&#xff09;写在前面&#xff1a; 作者之前都是在写js&#xff0c;所以这里介绍ts肯定是不能从头开始介绍了&#xff0c;主要在js的基础上介绍ts关于类型的几个特性&#xff0c;以及ts的安装还有配置问题 &#xff08;1&#xff09;ts和js是什么关系 通俗点来…...

网络参考资料汇总(1)

将这段时间参考的各路大佬的资料加以汇总分类&#xff1a; &#xff08;1&#xff09;FFmpeg: 基于FFmpeg进行rtsp推流及拉流&#xff08;详细教程&#xff09; Linux 编译安装 FFmpeg 步骤&#xff08;带ffplay&#xff09; Jetson 环境安装(三):jetson nano配置ffmpeg和ngin…...

Remove和RemoveLast用法

LeetCode 46 全排列 先贴代码 class Solution {List<List<Integer>> result new ArrayList<>();List<Integer> temp new ArrayList<>();public List<List<Integer>> permute(int[] nums) {dfs(nums, 0);return result;}public v…...

(一) 使用 Hugo 搭建个人博客保姆级教程(上篇)

手把手教你如何从0开始构建一个静态网站&#xff0c;这不需要有太多的编程和开发经验和时间投入&#xff0c;也基本不需要多少成本&#xff08;除了个性化域名&#xff09;&#xff0c;使用GitHub和Hugo模板即可快速构建和上线一个网站。 目标读者 本文档适用于以下用户&…...

数据结构之栈

栈的模拟实现 1.栈的概念2.栈的方法3.栈的模拟实现(代码)3.1 接口My_Stack3.2 StackList3.3 异常类StackException3.4 测试类Test 1.栈的概念 2.栈的方法 3.栈的模拟实现(代码) 3.1 接口My_Stack 3.2 StackList 3.3 异常类StackException 3.4 测试类Test...

wireshark of tshark tools v3.4.0版本 支持json

tshark(1) Install tshark (Wireshark) Ver.3.4.0 on CentOS7 --It must be "ps", "text", "pdml", "psml" or "fields". TCP 协议中的三次握手和四次挥手是 TCP 连接建立和关闭的过程。 三次握手 客户端向服务器发送 SYN…...

Python开源项目月排行 2023年9月

#2023年9月2023年9月9日1fishdraw这个项目是用来随机生成一条鱼的&#xff0c;这条鱼特别的稀奇古怪&#xff0c;这个项目不依赖任何库&#xff0c;支持 svg, json, csv 等格式。2vizro一个用于创建模块化数据可视化应用程序的工具包。在几分钟内快速自助组装定制仪表板 - 无需…...

uniapp项目实践总结(二十五)苹果 ios 平台 APP 打包教程

导语:当你的应用程序开发完成后,在上架 ios 应用商店之前,需要进行打包操作,下面就简单介绍一下打包方法。 目录 准备工作注册账号生成证书打包配置准备工作 在打包之前,请保证你的 uniapp 应用程序编译到 ios 模拟器或者是真机调试基座环境下是可以正常运行的,苹果打包…...

MySQL查询(基础到高级)

一、单表查询&#xff1a; 1.基本查询&#xff1a; 1.1 查询多个字段&#xff1a; 1.查询所有字段&#xff1a; select * from 表名;2.查询指定字段&#xff1a; select 字段1,字段2 from 表名; 1.2 去除重复记录 select distinct "字段" FROM "表名"; …...

电脑通过串口助手和51单片机串口通讯

今天有时间把电脑和51单片机之间的串口通讯搞定了&#xff0c;电脑发送的串口数据&#xff0c;单片机能够正常接收并显示到oled屏幕上&#xff0c;特此记录一下&#xff0c;防止后面自己忘记了怎么搞得了。 先来两个图片看看结果吧&#xff01; 下面是串口3.c的文件全部内容&a…...

【Linux】线程详解完结篇——信号量 + 线程池 + 单例模式 + 读写锁

线程详解第四篇 前言正式开始信号量引例信号量的本质信号量相关的四个核心接口生产消费者模型用环形队列实现生产者消费者模型基于环形队列的生产消费模型的原理代码演示单生产者单消费者多生产者多消费者 计数器的意义 线程池基本概念代码 单例模式STL,智能指针和线程安全STL中…...

弧度、圆弧上的点、圆的半径(r)、弧长(s)之间的关系

要计算弧度和圆弧上的点&#xff0c;需要知道以下几个要素&#xff1a; 圆的半径&#xff08;r&#xff09;&#xff1a;即圆的中心到圆周上任意一点的距离。 弧长&#xff08;s&#xff09;&#xff1a;从圆周上的一个点到另一个点所经过的弧长。 弧度&#xff08;θ&#x…...

[AOSP] [JNI] [Android] AOSP中使用JNI

一. 简要 &#x1f34e; JNI是Java Native Interface的缩写&#xff0c;它提供了若干的API实现了Java和其他语言的通信&#xff08;主要是C&C&#xff09;。从Java1.1开始&#xff0c;JNI标准成为java平台的一部分&#xff0c;它允许Java代码和其他语言写的代码进行交互。J…...

GEE案例——如何使用长时序影像实现多波段图像加载(不同层土壤湿度)

简介: 在GEE中实现时序图像的加载主要的目的是查看影像波段或者指数的变化,这里我们使用的主要是加载常规的4个波段,然后添加一个复合波段,复合波段主要的是求4个波段的平均值,然后再次加入到原有的4个波段的时序图中。这里面主要的技术难点一个是图表的设定,另外一个就…...

Cloudflare进阶技巧:缓存利用最大化

1. 引言 cloudflare我想你应该知道是什么&#xff0c;一家真正意义上免费无限量的CDN&#xff0c;至今未曾有哥们喷它的。当然&#xff0c;在国内的速度确实比较一般&#xff0c;不过这也不能怪它。 CDN最大的特色&#xff0c;我想就是它的缓存功能&#xff0c;达到防攻击&am…...

想要精通算法和SQL的成长之路 - 二叉树的判断问题(子树判断 | 对称性 | 一致性判断)

想要精通算法和SQL的成长之路 - 二叉树的判断问题 前言一. 相同的树二. 对称二叉树三. 判断子树 前言 想要精通算法和SQL的成长之路 - 系列导航 一. 相同的树 原题链接 这题目典型的递归题&#xff1a; 如果两个节点都是null&#xff0c;我们返回true。如果两个节点一个nul…...

外贸淘宝网站建设/文件关键词搜索工具

作者简介古映杰&#xff0c;携程研发高级经理&#xff0c;负责前端框架和基础设施的设计、研发与维护。开源项目react-lite和react-imvc作者。尤雨溪6月份发布了 Vue Function-based API RFC&#xff0c;说是 3.0 最重要的 RFC。文章发布后&#xff0c;引起了许多人的讨论和争执…...

江苏连云港网站建设公司/牡丹江seo

会有如题的思考&#xff0c;是因为我一直有一个疑问java文件的编码会影响字符串的编码嘛&#xff1f; 因此自然而然就想到了java编译后的文件的编码。 1 javac在控制台编译java类文件 手动建立一个java文件Demo.java&#xff0c;并保存。 此时Demo.java文件的编码为ANSI,中…...

wordpress 密码失败/深圳关键词推广

CSS3属性box-shadow使用详细教程 box-shadow&#xff1a;length length length length color length&#xff1a;阴影水平偏移值 length&#xff1a;阴影垂直偏移值 length&#xff1a;阴影模糊值 length&#xff1a;阴影边框 color&#xff1a;阴影颜色 说明&#xff1a;设置…...

亚马逊注册没有公司网站怎么做/小网站怎么搜关键词

Python 实现用户登录系统 案例 一&#xff08;基于hashlib & sys&#xff09;基于hashlib 库MD5算法对用户密码进行加密用户名和密码信息存储在内存中 import sys import hashlib"""实现一个用户登录系统&#xff0c;用户可以输入用户面进行用户的注册、用户…...

网站建设分录/线上营销模式

定义结构 为了定义结构&#xff0c;您必须使用 struct 语句。struct 语句定义了一个包含多个成员的新的数据类型&#xff0c;struct 语句的格式如下&#xff1a; struct type_name { member_type1 member_name1; member_type2 member_name2; member_type3 member_name3; . . …...

wordpress怎么备案/温州seo公司

文章目录1、背景2、腾讯开放平台名片OCR接口2.1 文档参考2.2 小程序OCR功能主要JS代码实现3、微信小程序名片OCR功能接入3.1 微信小程序首页设计3.2 扫名片功能实现3.2.1 识别页面3.2.2 识别程序4 名片识别验证4.1 名片拍照4.2 名片识别1、背景 最近在做一个CRM微信小程序工具…...