使用c语言实现了一个简单的web服务器。程序支持html,css,js,jpg,gif格式的请求
#include<stdio.h> #include<fcntl.h> #include<netinet/in.h> #include<arpa/inet.h> #include<unistd.h> #include<sys/types.h> #include<sys/stat.h> #include<string.h> #include<stdlib.h> #define PORT 12345 #define WebRoot /home/meng/webpage /** * * 字符串s1是否以s2结束 */ int endsWith(char s1[],char s2[]){ int len1 = strlen(s1); int len2 = strlen(s2); int i=len1-1,j=len2-1; if(len1<len2)return 0; for(;i>=0&&j>=0;i--,j--){ if(s1[i]!=s2[j])return 0; } return 1; } int main(){ int sockfd,fd,client; struct sockaddr_in addr; int len=sizeof(addr); char recbuf[2048]; //socket连接 if((sockfd=socket(AF_INET,SOCK_STREAM,0))<0){ perror("socket.\n"); exit(1); } //设置IP端口 bzero(&addr,sizeof(addr)); addr.sin_family=AF_INET; addr.sin_port=htons(PORT); addr.sin_addr.s_addr=inet_addr("127.0.0.1"); //bind if(bind(sockfd,(struct sockaddr*)&addr,sizeof(addr))<0){ perror("bind.\n"); exit(1); } //listen 最大连接数 if(listen(sockfd,10)<0){ perror("listen.\n"); exit(1); } printf("listening...\n"); while(1){ //取得客户端的标识 if((client=accept(sockfd,(struct sockaddr*)&addr,&len))<0){ perror("accept.\n"); exit(1); } //读取请求的头部 int buf=0; if((buf=read(client,recbuf,2048))>=0){ recbuf[buf]='\0'; } //printf("%s\n",recbuf); char *token=strtok(recbuf," "); //获得HTTP请求第一行中间部分,也就是URI if(token!=NULL){ token=strtok(NULL," "); } char type[256]; /** * 根据请求资源结尾的扩展名不同, * 响应不同mine类型 */ if(endsWith(token,".jpg")){ strcpy(type,"image/jpeg\r\nAccept-Ranges:bytes"); }else if(endsWith(token,".gif")){ strcpy(type,"image/gif"); }else if(endsWith(token,".js")){ strcpy(type,"text/javascript"); }else if(endsWith(token,".css")){ strcpy(type,"text/css"); }else{ strcpy(type,"text/html"); } //读取文件内容 char filePath[1024]; char content[2048*512]; int fileSize; strcpy(filePath,"/home/meng/webpage"); strcat(filePath,token); fd=open(filePath,O_RDONLY,0766); if(fd==-1){ strcpy(content,"Not Found"); }else{ fileSize=read(fd,content,sizeof(content)); //printf("%d\n",strlen(content)); content[fileSize]='\0'; if(fileSize<=0)strcpy(content,"Not Found"); close(fd); } if(fileSize<=0){ fileSize=strlen("Not Found"); } char sendBuf[2048*1024]; char tmp[20]; sprintf(tmp,"%d",fileSize); memset(sendBuf,'\0',sizeof(sendBuf)); //返回HTTP响应的头部信息 //所有的返回状态都是200,暂不做404等其它响应状态的判断工作 strcat(sendBuf,"HTTP/1.1 200 OK\r\n"); strcat(sendBuf,"Server:MENGXIANLU\r\n"); strcat(sendBuf,"Content-Length:"); strcat(sendBuf,tmp); strcat(sendBuf,"\r\n"); strcat(sendBuf,"Content-Type: "); strcat(sendBuf,type); strcat(sendBuf,"\r\n"); //下面极其重要,表示响应头部的结束。 //头部结束后就是正文部分了 strcat(sendBuf,"\r\n"); /** 响应头部 END */ int i,j; /** 响应内容(正文) */ /** 不能使用 strcat进行字符串的连接了。*/ /**如果请求的是图片,其字节码中有可能包含'\0'如果使用strcat有可能造成信息的截断*/ for(i=0,j=strlen(sendBuf);i<fileSize;i++,j++){ sendBuf[j]=content[i]; } /** 一切准备就绪 */ sendBuf[j]='\0'; /**结果返回给客户端*/ write(client,sendBuf,j); close(client); } close(sockfd); return 0; }