简单的web服务器实现

#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 MAXLINE 2048  
#define PORT 12345  
#define WebRoot "/home/xrf/www"   

/*  字符串s1 是否以字符串 s2结尾 是返回1,不是返回0 */
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 listenfd,connfd;  
  	struct sockaddr_in addr;  
  	int len=sizeof(addr);  
  
	/* 创建TCP套接字 */
  	if((listenfd = 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=htonl(INADDR_ANY);  

	/*  在套接字上绑定相应的套接字地址结构 */
  	if(bind(listenfd, (struct sockaddr*)&addr, sizeof(addr)) < 0){  
    		perror("bind.\n");  
    		exit(1);  
  	}  
    
	/* 使套接字变成监听套接字,并指定同时能连接的最大客户数 */
  	if(listen(listenfd,10)<0){  
    		perror("listen.\n");  
    		exit(1);  
  	}  
    
  	//printf("listening...\n");  
  	while(1){   

			/*  接受客户的连接请求,并返回连接套接字 */
      		if((connfd = accept(listenfd,(struct sockaddr*)&addr,&len)) < 0){  
          		perror("accept.\n");  
          		exit(1);  
      		}
		
			/*  创建子进程来处理已连接的请求,父进程继续监听客户端连接请求 */
			if(fork() == 0){
      			int buf=0;
    			char type[256];  
  				int fd,fsize;
  				char recbuf[MAXLINE];
				char filePath[256]=WebRoot;  
      			char content[2048*512];  
				char sendBuf[2048*1024]; 
				int i,j;  

				/*子进程关闭监听套接字描述符 */
				close(listenfd); 
				
				/* 获取客户端发来的请求内容 */
      			if((buf=read(connfd,recbuf,sizeof(recbuf))) >= 0) 
          			recbuf[buf]='\0'; 
   
      			//printf("%s\n",recbuf);  

				/* 对获取到的请求内容进行分割,以提取请求内容的类型 */
      			char *token=strtok(recbuf," ");  
    			//printf("%s\n",token);  //一般是http请求头的get 
      			if(token!=NULL){  
          			token=strtok(NULL," "); 
					//printf("%s\n",token); //请求内容 
      			}
				
				/* 判断请求类型 */
    			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");  
    			}
    
      			strcat(filePath,token);  
      			fd=open(filePath,O_RDONLY,0766);  
    			if(fd == -1){  
       				strcpy(content,"Not Found");  
      			}else{  
          			fsize=read(fd,content,sizeof(content));  
      				content[fsize]='\0';  
          			if(fsize <= 0)
						strcpy(content,"Not Found");  
          			close(fd);  
      			}  
 
      			memset(sendBuf,'\0',sizeof(sendBuf)); 
			    /* 填充 http header内容 */ 
      			sprintf(sendBuf,"HTTP/1.1 200 OK\r\nServer:MENGXIANLU\r\nContent-Length:%dContent-Type:%s\r\n\r\n",fsize,type);  

    			/* 填充 http body 内容 */  
    			for(i=0,j=strlen(sendBuf);i<fsize;i++,j++){  
      				sendBuf[j]=content[i];  
    			}  
 
   	 			sendBuf[j]='\0';  
      			write(connfd,sendBuf,j);  
				exit(0);
			}
  			close(connfd);  
		}
  		return 0;  
}  


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值