web服務器

//============================================================================
// 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;
}

運行示例:


發佈了56 篇原創文章 · 獲贊 1 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章