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

news2024/11/18 17:29:57

实现效果如下:

图片可以直接显示 

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 0
        while(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");
            }
        }
        #else
        off_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 socket
        epoll_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	20

bool 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 1
        while(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");
            }
        }
        #else
        off_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 pipes
	signal(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.coloradmin.cn/o/1059736.html

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

相关文章

SpringBoot中使用拦截器

拦截器属于MVC中的内容 SpringBoot项目,引入web依赖即可 需要访问的控制器 拦截器第一步实现HandlerInterceptor接口 第二步实现WebMvcConfigurer接口,并重写addInterCeptors()方法,将自定义的拦截器注册 也就是说这里add进去拦截的请求,才会进入到prehandle方法,这里放行的请…

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

嵌入式Linux应用开发-驱动大全-同步与互斥① 第一章 同步与互斥①1.1 内联汇编1.1.1 C语言实现加法1.1.2 使用汇编函数实现加法1.1.3 内联汇编语法1.1.4 编写内联汇编实现加法1.1.5 earlyclobber的例子 1.2 同步与互斥的失败例子1.2.1 失败例子11.2.2 失败例子21.2.3 失败例子3…

AMD GPU 内核驱动分析(三)-dma-fence 同步工作模型

在Linux Kernel 的AMDGPU驱动实现中&#xff0c;dma-fence扮演着重要角色&#xff0c;AMDGPU的Render/解码操作可能涉及到多个方面同时引用buffer的情况&#xff0c;以渲染/视频解码场景为例&#xff0c;应用将渲染/解码命令写入和GPU共享的BUFFER之后&#xff0c;需要将任务提…

记录UNIAPP打包苹果iOS·APP

用到生成的四个文件:1-1.CSR证书文件、2-2.CER证书文件、3-3.PP文件【证书Profiles文件】、4-4.P12文件【证书私钥】 1. 生成CSR证书文件: 2. 操作苹果后台:Sign In - Applehttps://developer.apple.com/account/resources/certificates/list

高效的开发流程搭建

目录 1. 搭建 AI codebase 环境kaggle的服务器1. 搭建 AI codebase 环境 python 、torch 以及 cuda版本,对AI的影响最大。不同的版本,可能最终计算出的结果会有区别。 硬盘:PCIE转SSD的卡槽,, GPU: 软件源: Anaconda: 一定要放到固态硬盘上。 VS code 的 debug功能…

嵌入式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函数的…

关于将对象转成JSON格式的一些问题

1.问题现象&#xff1a; 在ssm项目中&#xff0c;一个controller返回Msg对象&#xff08;自定义Javabean对象&#xff09;&#xff0c;然后利用SpringMVC的ResponseBody注解自动将Msg对象转化成JSON格式&#xff0c;返回给客户端&#xff0c;但是客户端接收到的json字符串只有…

「专题速递」数字人直播带货、传统行业数字化升级、远程协作中的低延时视频、地产物业中的通讯终端...

音视频技术作为企业数字化转型的核心要素之一&#xff0c;已在各行各业展现出广泛的应用和卓越的价值。实时通信、社交互动、高清视频等技术不仅令传统行业焕发新生&#xff0c;还为其在生产、管理、服务提供与维护等各个领域带来了巨大的助力&#xff0c;实现了生产效率和服务…

打字速度测试,生成您的打字速度证书?

趁着十一国庆之际&#xff0c;开发完成了打字侠的速度测试功能。我自己的打字速度约为56字/分钟&#xff0c;算是盲打中速度比较快的。下面是我的打字荣誉证书&#xff0c;欢迎大家免费测试自己的打字速度。 你也想来测试一下自己的打字速度吗&#xff1f; 打字侠速度测试地址…

2023最新简易ChatGPT3.5小程序全开源源码+全新UI首发+实测可用可二开(带部署教程)

源码简介&#xff1a; 2023最新简易ChatGPT3.5小程序全开源源码全新UI首发&#xff0c;实测可以用&#xff0c;而且可以二次开发。这个是最新ChatGPT智能AI机器人微信小程序源码&#xff0c;同时也带部署教程。 这个全新版本的小界面设计相当漂亮&#xff0c;简单大方&#x…

「算法小记」-1:Ackermann函数/阿克曼函数的一点思考解法【递归/非递归/堆栈方法】(C++ )

&#x1f60e; 作者介绍&#xff1a;我是程序员洲洲&#xff0c;一个热爱写作的非著名程序员。CSDN全栈优质领域创作者、华为云博客社区云享专家、阿里云博客社区专家博主、前后端开发、人工智能研究生。公粽号&#xff1a;程序员洲洲。 &#x1f388; 本文专栏&#xff1a;本文…

Java架构师角度看架构

目录 1 导学1.1 技术提升依然突破不了职业的瓶颈1.2 技术提升可薪资依然涨不上去1.3 学了架构课程依然觉得自己成长很慢 2 架构的基本认识2.1 什么是架构2.2 为什么要做架构设计 3 深入理解和认识架构。3.1 架构定义的行为。3.2 架构关注系统的主要元素3.3 平衡关注点3.4 架构会…

站长如何能够做到网站的全方位防护呢?

随着互联网的急剧崛起&#xff0c;网站已成为企业塑造品牌形象和吸引潜在客户的首要渠道之一。然而&#xff0c;伴随着这种便捷性&#xff0c;网站安全问题也愈发凸显。DDOS&#xff08;分布式拒绝服务攻击&#xff09;和CC&#xff08;恶意请求攻击&#xff09;攻击成为了黑客…

ROS基础

E: Unable to locate package ros-kinetic-turtle-tf ROS Kinetic 学习笔记 (古月居) https://www.bilibili.com/video/BV1hc411n7N7/ 一、认识ROS 大纲 ROS的总体设计 系统实现 三个层次 1 主要是话题、服务通信模型的实现&#xff1b; 话题&#xff1a; RPC介绍&#…

顾樵 量子力学I 导读(1)

波函数与薛定谔方程 薛定谔方程的获得 经典电磁波理论与德布罗意关系 波函数的性质 波函数是平方可积函数&#xff08;归一化条件&#xff09;波函数和波函数的导数是连续的波函数的单值的波函数在势场奇点以外的地方连续力学量的平均值与期待值 粒子动量的期望值Ehrenfests th…

采用python中的opencv2的库来运用机器视觉移动物体

一. 此次我们来利用opencv2来进行机器视觉的学习 1. 首先我们先来进行一个小的案例的实现. 这次我们是将会进行一个小的矩形手势的移动. import cv2 from cvzone.HandTrackingModule import HandDetectorcap cv2.VideoCapture(0) # cap.set(3, 1280) # cap.set(4, 720) col…

1.1 数据库系统概述

思维导图&#xff1a; 前言&#xff1a; **数据库前言笔记&#xff1a;** 1. **数据库的价值** - 数据管理的高效工具 - 计算机科学的关键分支 2. **信息资源的重要性** - 现代企业或组织的生存和发展关键 - 建立有效的信息系统至关重要 3. **数据库的应用范围**…

Vue中如何进行移动端手势操作

当开发移动端应用程序时&#xff0c;手势操作是提高用户体验的关键部分之一。Vue.js是一个流行的JavaScript框架&#xff0c;它提供了一种简单而强大的方式来实现移动端手势操作。本文将介绍如何在Vue.js中进行移动端手势操作&#xff0c;包括基本手势&#xff0c;如点击、滑动…