httpserver 下载服务器demo

实现效果如下:

图片可以直接显示 

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

httpserver 下载服务器demo_第1张图片

httpserver 下载服务器demo_第2张图片

httpserver 下载服务器demo_第3张图片

httpserver 下载服务器demo_第4张图片

单线程 还有bug

代码如下  先放上来 

#include "httpserver.h"
#include "stdio.h"
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 


#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,"%s",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),
                "",name,name,st.st_size);
        }
        else
        {
            sprintf(buf+strlen(buf),
                "",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,"
%s%ld
%s%ld
"); 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 0) { if(total+read_len

你可能感兴趣的:(服务器,算法,c++)