C语言制作web服务器(静态)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <unistd.h>

#define PORT 50000

int main(){
	struct sockaddr_in s_addr;

	socklen_t addrlen = sizeof(struct sockaddr_in);
	int c_sockfd;
	int s_sockfd = socket(AF_INET,SOCK_STREAM,0);
	if(s_sockfd == -1){
		perror("socket error!");
		exit(1);
	}

	memset(&s_addr,0,sizeof(struct sockaddr));
	s_addr.sin_family = AF_INET;
	s_addr.sin_port = htons(PORT);
	s_addr.sin_addr.s_addr = inet_addr("127.0.0.1");

	int opt = 1;
	setsockopt(s_sockfd,SOL_SOCKET,SO_REUSEADDR,&opt,1);

	if(bind(s_sockfd,(struct sockaddr *)(&s_addr),addrlen) == -1){
		perror("bind error!");
		exit(1);
	}

	if(listen(s_sockfd,10) == -1){
		perror("listen error!");
		exit(1);
	}

	printf("start accepting!\n");
    //accept
	char path[100];
	struct sockaddr_in c_addr;
	while(1){
	c_sockfd = accept(s_sockfd,(struct sockaddr *)(&c_addr),&addrlen);
	if(c_sockfd == -1){
		perror("accept error!");
		exit(1);
	}
	char buf[1024];
	int len;
	 memset(buf,0,sizeof(buf));
	 read(c_sockfd,buf,sizeof(buf));  //从浏览器读取请求内容
	 //print message from browser
	 printf("%s",buf);           
	 char filename[50];
	 char *s = buf;
	 char *d = filename;
	 while(*s++ != '/');
	 while(*s != ' '){
		 *d = *s;
		 d++;
		 s++;
	 }
	 *d = 0;
	 printf("filename:%s\n",filename);
	 //read file
	 memset(path,0,sizeof(path));
	 sprintf(path,"/home/ben/c.d/%s",filename);
	 int fd = open(path,O_RDONLY);
	 if(fd == -1){
		 //TODO 404    // 所请求的文件不存在
		 write(c_sockfd,"HTTP/1.1 404\n",13);
		 write(c_sockfd,"Content-Language: zh-cn\n",24);
		 write(c_sockfd,"Content-Type: text/html; charset=UTF-8\n\n",40);
		 write(c_sockfd,"<h1 style=\"background:gray\">Resource Not Found!</h1>",53);
		 write(c_sockfd,"<img src=\"error.jpg\"/>",23);
	 }else{
		 //TODO 200   // 有这个文件,往浏览器写文件的内容
		 write(c_sockfd,"HTTP/1.1 200 OK\n",16);
		 write(c_sockfd,"Content-Language: zh-cn\n",24);
		 //extract suffix of filename   //获取文件的拓展名
		 char suffix[10];
		 memset(suffix,0,sizeof(suffix));
		 s = filename;
		 d = suffix;
		 while(*s++ != '.');
		 while(*s){
			 *d = *s;
			 d++;
			 s++;
		 }
		 printf("suffix:%s\n",suffix);

		 if(strcmp("html",suffix) == 0                    //如果是一个html文档
		      ||strcmp("htm",suffix) == 0
		 ){
			 write(c_sockfd,"Content-Type: text/html; charset=UTF-8\n\n",40);
		 }else if(strcmp("jpg",suffix) == 0                   //如果是一个图片
				 ||strcmp("jpeg",suffix) == 0
				 ||strcmp("png",suffix) == 0
				 ||strcmp("gif",suffix) == 0
		 ){
			 write(c_sockfd,"Content-Type: image/jpeg\n\n",26);
		 }
		 while(1){
			 memset(buf,0,sizeof(buf));
			 len = read(fd,buf,sizeof(buf));
			 write(c_sockfd,buf,len);
			 if(len < sizeof(buf)){
				 break;
			 }
		 }
		 close(fd);
	 }
	 shutdown(c_sockfd,SHUT_RDWR);
	}
	close(s_sockfd);


	pthread_exit(0);

}

步骤:

浏览器(客户端)访问服务器时发送的是这些内容:

GET /index.html HTTP/1.1

Host: 127.0.0.1:50000

User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20131029 Firefox/17.0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8

Accept-Language: en-US,en;q=0.5

Accept-Encoding: gzip, deflate

Connection: keep-alive

Cache-Control: max-age=0

GET /index.html HTTP/1.1
这里给了一些有用的信息,可以看出用的是get请求,后面是要访问的页面。因为是例子我把这个写成index.html。
由这个信息,可以知道浏览器要访问index.html页面,我们在程序中需要把这个内容解析出来,然后打开对应的html文件。
首先给浏览器发送http协议头,后面发送html文件内容就ok了,浏览器就可以显示你发送过去的页面了。

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 游动-白 设计师:白松林 返回首页