web/http服务器实现


项目开发流程

  1. 需求分析:实现基本的HTTP服务器,支持浏览器的访问(支持标准http协议)
    • 接收浏览器发送HTTP请求;
    • 解析请求数据,请求方式(GET),请求文件(html…),协议版本;
    • 根据请求构建响应头,发送响应头:
      HTTP/1.1 200 Ok
      HTTP/1.1 404 File not found
    • 根据请求文件,从服务器目录中获取对应的文件,发送给浏览器。
  2. 概要设计:绘制基本框图
    在这里插入图片描述
  3. 详细设计:绘制程序流程图
    web整体框架总流程
    总流程
    最外层流程
    在这里插入图片描述

程序读取配置文件流程
在这里插入图片描述
子进程处理客户端请求流程
在这里插入图片描述
服务器初始化流程
在这里插入图片描述
正常请求响应流程
在这里插入图片描述
响应404流程
在这里插入图片描述
4. 编码:编写程序代码

程序编码

  1. 创建TCP并发服务器(多进程、多线程)
    从配置中读取端口号–>将端口号写入配置文件configure中,创建服务器时从配置文件中读取端口号。(在启动服务器时添加-b选项使得服务器工作在守护进程模式)
  int sockfd = socket(AF_INET,SOCK_STREAM,0);
  if(-1 == sockfd){
	perror("socket");
	return -1;
  }
  struct sockaddr_in server_addr;
  server_addr.sin_famlily = AF_INET;
  server_addr.sin_port = htons(8080)
  server_addr.sin_addr.s_addr = INADDR_ANY;

  if(bind(sockfd,(struct sockaddr*)&server_addr,
		sizeof(server_addr)) == -1){
	perror("bind");
	return -1;
  }
  listen(sockfd,10);
  
  //准备和客户端通信的socket套接字
  int client_fd;
  struct sockaddr_in client_addr;
  socklen_t len = sizeof(client_addr);

  client_fd = accept(sockfd,&client_addr,&len);

  //创建子进程fork
  //创建子线程pthread_create
  char buf[1024]={0};
  read(client_fd,buf,1024);
  puts(buf);//客户端发来的请求信息
  1. 接收客户端请求,打印请求数据,了解浏览器发来的请求数据包的内容。
  2. 解析请求数据包,保存必要数据
typedef struct{
   char method[12];//请求方法,GET 
   char path[128]; //请求文件,http、jpg..
   char protocol[20];//请求协议版本,HTTP/1.1
}request_t;
  1. 创建响应头结构体
typedef struct{
   int status;//状态码 200,404
   char protocol;//协议版本,HTTP/1.1
   char file_type[32];//类型信息
}response_t

  1. 从服务器目录(www)查找请求文件是否存在,存在则返回status=200,否则status=404.
  2. 构建响应头
  协议版本:与请求行获取的协议版本一致
  类型信息:根据请求的文件后缀匹配
  eg:
  如果客户请求是html文件,类型信息为"text/html"
  同理支持如下类型:
  *.html 	--> "text/html"
  *.jpg/*.jpeg 	--> "image/jpeg"
  *.png 	--> "image/png"
  *.gif		--> "image/gif"
  *.css 	--> "text/css" 
  ...
  1. 发送响应头给客户端
eg:
write("HTTP/1.1 200 OK\r\n");
write("Content-Type:text/html\r\n");
write("\r\n");
  1. 发送请求的文件
/*
如果status==200,说明请求文件存在,打开文件将文件内容发送给http客户端。
如果status==404,说明请求文件不存在,
发送"www/error.html"
*/

int fd = open("要给浏览器发送的文件")int bytes_read=0;
int bytes_write=0;
int buffer[1024] = {0};
char* ptr;
while(bytes_read = read(fd,buffer,1024)){
   if(bytes_read == -1){break;}
   else if(bytes_read > 0){
  	ptr = buffer;
	while(bytes_write =
		write(client_fd,ptr,bytes_read)){
	   if(bytes_write == bytes_read){//写完
 	   	break; 
	   }
   	   else{//只写一部分
 	      ptr += bytes_write
	      bytes_read -= bytes_write;
	   }
	}
   }
}
  1. 关闭连接

项目实例

发布了102 篇原创文章 · 获赞 27 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/qq_37596943/article/details/104219523