#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;
}
简单的web服务器实现
最新推荐文章于 2022-07-14 08:14:17 发布