Linux下实现web服务器

说明:暂时只是实现了静态网页的响应

  1 #include <stdio.h>
  2 #include <sys/types.h>          /* See NOTES */
  3 #include <sys/socket.h>
  4 #include <string.h>
  5 #include <arpa/inet.h>
  6 #include <unistd.h>
  7 #include <signal.h>
  8 #include <sys/wait.h>
  9 #include <sys/stat.h>
 10 #include <fcntl.h>
 11 #include <stdlib.h>
 12 
 13 #define PORT 8000
 14 char* msg_err="HTTP/1.1 404 NO FOUND\r\nContent-Type:text/html\r\n\r\n";
 15 char* msg_text="HTTP/1.1 200 OK\r\nContent-Type:text/html\r\n\r\n";
 16 char* msg_jpg="HTTP/1.1 200 OK\r\nContent-Type:image/jpg\r\n\r\n";
 17 char* msg_png="HTTP/1.1 200 OK\r\nContent-Type:image/png\r\n\r\n";
 18 char* work_dir="/home/soft01/Hector/Unixc/webProject/hah/www";
 19 char* work_dir_err="/home/soft01/Hector/Unixc/webProject/hah/err_404.html";
 20 
 21 //定义http协议 结构体
 22 typedef struct http{
 23     char method[12];  
 24     char filename[128];
 25     char protol[16];
 26 }utr_t;
 27 
 28 //自定义信号处理函数
 29 //回收子进程
 30 void sig_do(){
 31     wait(NULL);
 32     return;
 33 }
 34 
 35 //响应
 36 void write_client(char* str,int fd,char* msg){
 37     char status[100000];
 38     int fd_open=open(str,O_RDONLY);
 39     if(fd_open==-1){
 40         perror("open");
 41         int fd_open=open(work_dir_err,O_RDONLY);
 42         int nlen=read(fd_open,status,100000);
 43         write(fd,msg_err,strlen(msg_err));
 44         write(fd,status,nlen);
 45         return;
 46     }
 47     int nlen=read(fd_open,status,100000);
 48     write(fd,msg,strlen(msg));
 49     write(fd,status,nlen);
 50     return;
 51 }
 52 
 53 //判断图片文本
 54 void judge_text_or_png(char* str,int fd){
 55     char* msg="<html>\n<body>\n<h1>404\n</body>\n</html>\n";
 56     if(str==NULL){return;}
 57     char* tmp=NULL;
 58     if((tmp=strstr(str,".jpg"))!=NULL){
 59         write_client(str,fd,msg_jpg);
 60     }
 61     else if((tmp=strstr(str,".png"))!=NULL){
 62         write_client(str,fd,msg_png);
 63     }
 64     else if((tmp=strstr(str,".html"))!=NULL){//文本
 65         write_client(str,fd,msg_text);
 66     }
 67     else{
 68         write(fd,msg_err,strlen(msg_err));
 69         write(fd,msg,strlen(msg));
 70     }
 71     return;
 72 }
 73 
 74 //子进程响应客户端
 75 void request_do(int fd){
 76     utr_t http;
 77     char path[128];
 78     char buf[1024];
 79     int len=read(fd,buf,1024);
 80     sscanf(buf,"%s %s %s\r\n",http.method,http.filename,http.protol);
 81     if(strcmp(http.filename,"/")==0){
 82         strcpy(http.filename,"/index.html");
 83     }
 84 
 85     strcpy(path,work_dir);
 86     strcat(path,http.filename);
 87     strcpy(http.filename,path);
 88     printf("method:%s filename:%s protol:%s\n", http.method,http.filename,http.protol);
 89     
 90     //判断图片文本
 91     judge_text_or_png(http.filename,fd);
 92     
 93     return;
 94 }
 95 
 96 int main(){
 97     struct sockaddr_in serv;
 98     struct sockaddr_in clie;
 99     socklen_t clie_len;
100     signal(SIGCHLD,sig_do);
101     //创建socket通讯端口
102     int sfd=socket(AF_INET,SOCK_STREAM,0);
103     if(sfd==-1){
104         perror("socket");
105         return -1;
106     }
107     
108     //初始化服务器serv
109     serv.sin_family=AF_INET;
110     serv.sin_port=htons(PORT);
111     serv.sin_addr.s_addr=htonl(INADDR_ANY);
112     //将sfd绑定到服务器
113     int b=bind(sfd,(struct sockaddr*)&serv,sizeof(serv));
114     if(b==-1){
115         perror("bind");
116         return -1;
117     }
118     listen(sfd,10);
119     while(1){
120         clie_len=sizeof(clie);
121         //建立和客户端的连接
122         int cfd=accept(sfd,(struct sockaddr*)&clie,&clie_len);
123         if(cfd==-1){
124             perror("accept");
125             return -1;
126         }
127         pid_t pid=fork();
128         if(pid==-1){
129             perror("pid");
130             return -1;
131         }
132         if(pid==0){//子进程
133             close(sfd);
134             //响应客户端请求
135             request_do(cfd);
136             close(cfd);
137             exit(0);
138         }
139         else{//父进程
140             close(cfd);
141         }
142 
143     }
144     return 0;
145 }

猜你喜欢

转载自www.cnblogs.com/qiuyuwutong/p/9385339.html