//============================================================================
// Name : CExercise.cpp
// Author : Haier
// Version : 0.1
// Copyright : Your copyright notice
// Description : webserver in c , Ansi-style
//============================================================================
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define PORT 32000
int endWith(char *src,char *dst)
{
int srclen=strlen(src);
int dstlen=strlen(dst);
int i,j;
if(srclen<dstlen)
{
return 0;
}
for(i=srclen-1,j=dstlen-1; i>=0 && j>=0; i--,j--)
{
if(src[i] != dst[j])
{
return 0;
}
}
return 1;
}
int main()
{
int serversockfd,clientsockfd;
struct sockaddr_in addr;
int addrlen=sizeof(addr);
char buffer[2048];
char type[256];
char filePath[1024];
char content[2048*512];
char sendBuf[2048*1024];
char fileLenth[20];
int fileSize;
int number;
int fd;
int i,j;
//建立套接字
if((serversockfd=socket(AF_INET,SOCK_STREAM,0))<0)
{
printf("%s",strerror(errno));
exit(1);
}
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");
//绑定端口
if(bind(serversockfd,(struct sockaddr*)&addr,sizeof(addr))<0)
{
printf("%s",strerror(errno));
exit(1);
}
//监听端口
if(listen(serversockfd,4)<0)
{
printf("%s",strerror(errno));
exit(1);
}
printf("webserver is started ...\n");
while(1)
{
if((clientsockfd=accept(serversockfd,(struct sockaddr*)&addr,(socklen_t*)&addrlen))<0)
{
printf("error1: %s\n",strerror(errno));
exit(1);
}
if((number=read(clientsockfd,buffer,sizeof(buffer))))
{
buffer[number]='\0';
}
//解析报文,判断请求资源类型
char *token=strtok(buffer," ");
if(token!=NULL)
{
token=strtok(NULL," ");
}
if(endWith(token,".jpg"))
{
strcpy(type,"image/jpeg\r\nAccept-Ranges:bytes");
}else if(endWith(token,".gif")){
strcpy(type,"image/gif");
}else if(endWith(token,".js")){
strcpy(type,"text/javascript");
}else if(endWith(token,".css")){
strcpy(type,"text/css");
}else{
strcpy(type,"text/html");
}
//查找并提供请求资源
strcpy(filePath,"/home/Lenovo/workspace/webserver/WebRoot");
strcat(filePath,token);
if((fd=open(filePath,O_RDONLY,0766))<0)
{
strcpy(content,strerror(errno));
printf("error2: %s\n",strerror(errno));
}else{
if((fileSize=read(fd,content,sizeof(content))))
{
content[fileSize]='\0';
}else{
strcpy(content,"Empty !");
}
close(fd);
}
//拼装报文
memset(sendBuf,'\0',sizeof(sendBuf));
strcat(sendBuf,"HTTP/1.1 200 OK\r\n");
strcat(sendBuf,"Server:MENGXIANLU\r\n");
strcat(sendBuf,"Content-Length:");
sprintf(fileLenth,"%d",fileSize);
strcat(sendBuf,fileLenth);
strcat(sendBuf,"\r\n");
strcat(sendBuf,"Content-Type: ");
strcat(sendBuf,type);
strcat(sendBuf,"\r\n");
strcat(sendBuf,"\r\n");
for(i=0,j=strlen(sendBuf); i<fileSize ; i++,j++)
{
*(sendBuf+j)=*(content+i);
}
*(sendBuf+j)='\0';
if((write(clientsockfd,sendBuf,j))<0)
{
printf("error3: %s\n",strerror(errno));
}
close(clientsockfd);
}
close(serversockfd);
return 0;
}
运行示例: