Linux下基于http的小型web服务器编写
来源:互联网 发布:新网互联域名证书 编辑:程序博客网 时间:2024/04/30 10:44
#pragma once#include<stdio.h>#include<stdlib.h>#include<string.h>#include<sys/types.h>#include<sys/socket.h>#include<sys/sendfile.h>#include<sys/stat.h>#include<fcntl.h>#include<netinet/in.h>#include<arpa/inet.h>#include<assert.h>#include<pthread.h>#include<errno.h>#define _DEF_PAGE_ "index.html"#define _SIZE_ 1024static void printLog(const char* const str,const char* const fun,int line);void usage(const char* const proc);int startup(char* ip,int port);void echo_error(int sock,int errno);int get_line(int sock,char* buf,int size);void clear_head(int sock);void echo_html(int sock,char* path,ssize_t size);void accept_request(int sock); void* handle_client(void* arg);//http.c#include"http.h" static void printLog(const char* const str,const char* const fun,int line){ printf("%s:%s:%d\n",str,fun,line);}void usage(const char* const proc){ assert(proc); printLog(proc,__FUNCTION__,__LINE__);}int startup(char* ip,int port){ assert(ip); int sock=socket(AF_INET,SOCK_STREAM,0); if(sock<0) { printLog(strerror(errno),__FUNCTION__,__LINE__); exit(1); } int opt=1; setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt)); struct sockaddr_in local; local.sin_family=AF_INET; local.sin_port=htons(port); if(strncmp(ip,"any",3)==0) { local.sin_addr.s_addr= INADDR_ANY; } else { local.sin_addr.s_addr=inet_addr(ip); } if(bind(sock,(struct sockaddr*)&local,sizeof(local))<0) { printLog(strerror(errno),__FUNCTION__,__LINE__); exit(1); } if(listen(sock,5)<0) { printLog(strerror(errno),__FUNCTION__,__LINE__); exit(1); } return sock;}void echoErr(int sock,int errno){ return;}int get_line(int sock,char* buf,int size){ assert(buf); int i=0; ssize_t _s=-1; char ch='\0';// printf("getLine"); while(i<size-1&&ch!='\n') { _s=recv(sock,&ch,1,0); if(_s>0) { if(ch=='\r') { if((_s=recv(sock,&ch,1,MSG_PEEK))) { if(_s>0&&ch=='\n') recv(sock,&ch,1,0); } } buf[i++]=ch; } else { buf[i++]='\n'; break; } }// printf("endddddddddddd"); buf[i]='\0'; return i;}void clear_head(int sock){ char buf[_SIZE_]; buf[0]='\0'; ssize_t _s=1; while(_s>0&&strcmp(buf,"\n")!=0) { _s=get_line(sock,buf,sizeof(buf)); }}void echo_html(int sock,char* path,ssize_t size){// printf("echo_htmlllllllllll\n");// printf("path:%s\n",path); int fd=open(path,O_RDONLY); if(fd<0) { printLog(strerror(errno),__FUNCTION__,__LINE__); exit(1); }// printf("fd:%d\n",fd); char* status_line="HTTP/1.0 200 ok\r\n\r\n"; send(sock,status_line,strlen(status_line),0);// printf("sock success,size:%d\n",size); if(sendfile(sock,fd,NULL,size)<0) { printf("error"); }// printf("sendfile success"); close(fd);}void accept_request(int sock){ char buf[_SIZE_];// int ret; // while((ret=get_line(sock,buf,sizeof(buf)))>0) // {// if(ret==0)// {// printLog(strerror(errno),__FUNCTION__,__LINE__);// break;// }// printf("%s",buf);// } int ret=-1; int i=0,j=0; char method[_SIZE_/2]; char url[_SIZE_]; char path[_SIZE_]; memset(method,'\0',sizeof(method)); memset(buf,'\0',sizeof(buf)); memset(path,'\0',sizeof(path)); memset(url,'\0',sizeof(url)); if(get_line(sock,buf,sizeof(buf))==0) { printLog("errno",__FUNCTION__,__LINE__); return; }// printf("%s",buf); i=j=0; while(!isspace(buf[i])&&i<strlen(buf)&&j<sizeof(method)-1) { method[j]=buf[i];//get method ++i; ++j; } method[j]='\0';// printf("method:%s\n",method); j=0; while(isspace(buf[i])) { ++i; } while(!isspace(buf[i])&&i<strlen(buf)&&j<sizeof(url)-1) { url[j]=buf[i]; ++j; ++i; } url[j]='\0';// printf("url:%s\n",url); int cgi=0; if(strcasecmp(method,"POST")!=0&&strcasecmp(method,"GET")!=0) { printf("error\n"); // echoErr(sock,1); return; }// printf("success\n"); if(strcasecmp(method,"POST")==0) { cgi=1; } if(strcasecmp(method,"GET")==0) {// printf("getttttttttttttttttttt\n"); char* query_string=url; while(*query_string!='\0'&&*query_string!='?') { ++query_string; } if(*query_string=='?') { *query_string='\0'; cgi=1; } ++query_string; sprintf(path,"htdocs%s",url);//sprintf// printf("path:%s\n",path); if(path[strlen(path)-1]=='/') { strcat(path,_DEF_PAGE_); }// printf("cgi=0,path:%s\n",path); struct stat st; if(stat(path,&st)<0)//not exist { printf("error"); return; } else if(S_IFDIR&st.st_mode)//dir {// printf("dirrrrrrrrrrr\n"); if(strcmp(path,"htdocs/_DEF_PAGE_")!=0) { strcpy(path,"htdocs/"); strcat(path,_DEF_PAGE_);// printf("hhhhhhhhhhhhhhhhhh"); } } else if((st.st_mode&S_IXUSR)||(st.st_mode&S_IXGRP)||(st.st_mode&S_IXOTH)) {// printf("xxxxxxxxxxxxxxxxxx\n"); cgi=1; } if(cgi) { //execute_cgi(sock,path,method,query_string); } else {// printf("echo_html\n"); fflush(stdout); clear_head(sock); echo_html(sock,path,st.st_size); } } close(sock);}void* handle_client(void* arg){ int sock=(int)arg; accept_request(sock); return NULL;} //main.c#include"http.h" int main(int argc,char* argv[]){ if(argc!=3) { usage(argv[0]); return 1; } char* ip=argv[1]; int port=atoi(argv[2]); int listen_sock=startup(ip,port); struct sockaddr_in client; socklen_t len=sizeof(client); fflush(stdout); while(1) { // printf("kkkkkkkkkkk"); // fflush(stdout); int new_sock=accept(listen_sock,(struct sockaddr*)&client,&len); if(new_sock<0) { printf("no client"); fflush(stdout); continue; } pthread_t id; // printf("con"); pthread_create(&id,NULL,handle_client,(void*)new_sock); pthread_detach(id);//set detach return val:0/errno } return 0;}
0 0
- Linux下基于http的小型web服务器编写
- 基于HTTP协议实现的小型web服务器
- Linux下小型web服务器boa的使用
- Linux下小型WEB服务器boa的使用0(转)
- Linux下小型WEB服务器boa的使用1(转)
- Linux下小型web服务器boa的使用
- Linux下小型WEB服务器boa的使用
- 利用http协议实现小型Web服务器
- Linux C++ 实现简易小型的Web服务器httpd
- Linux C++ 实现简易小型的Web服务器httpd
- 小型web服务器thttpd的学习总结(上)&小型web服务器thttpd的学习总结(下)
- 基于C++编写的简单web服务器
- 基于Http协议的Web服务器
- 基于HTTP协议的Web服务器
- linux--http服务器编写
- 小型的http服务器处于维护中
- 在android上如何编写一个小型web服务器
- linux下的http服务器
- 15.3 List接口特有方法
- ACL 过滤
- MacBookPro打造开发环境
- Laravel系列之windows环境安装配置(一)
- Intent传递对象的两种方式(putSerializable,putParelable)
- Linux下基于http的小型web服务器编写
- 欢迎使用CSDN-markdown编辑器
- JAVA中集合框架概述
- 【mybatis】IF判断的坑
- LINUX常用命令大全
- 笔记本安装WindowsXP系统时蓝屏了怎么办
- <AlertDialog>的简单用法与功能
- iOS多线程编程--NSOperation
- Nginx两种安装方式简述