实现高并发服务器(二)

本文介绍了如何优化高并发服务器,详细解析了读取文件的步骤,包括利用stat函数获取文件状态信息,并针对不同HTTP响应(501, 404, 400, 500)进行了处理。接着探讨了并发概念,讲解了pthread_create函数创建新线程以实现并发执行任务,以提升服务器处理请求的能力。" 109462227,8535427,VOS错误代码解析与排查指南,"['运维', '故障诊断', '系统故障', '网络问题', '错误解析']
摘要由CSDN通过智能技术生成

目录

一、读取文件

 1、501 http 响应

2、404 http 响应

3、400 http 响应 - BAD  REQUEST

4、500 http 响应 - 内部服务器错误

二、并发处理

1、并发概念

2、pthread_create函数


之前简单实现了minihttp,但是实际效果并不是很好,因为回复响应是指定的,现在进行完善。

首先我们需要针对响应去打开回复的文件

一、读取文件

文件概念简介

  inode - "索引节点",储存文件的元信息,比如文件的创建者、文件的创建日期、文件的大小等等。每个inode都有一个号码,操作系统用inode号码来识别不同的文件。ls -i  查看inode 号

关键函数:stat函数

作用:返回文件的状态信息

调用之前需要包含以下头文件

        #include <sys/types.h>

        #include <sys/stat.h>

        #include <unistd.h>

函数结构:

       int stat(const char *path, struct stat *buf);

       int fstat(int fd, struct stat *buf);

       int lstat(const char *path, struct stat *buf);


path:

文件的路径

buf:

传入的保存文件状态的指针,用于保存文件的状态

返回值:

成功返回0,失败返回-1,设置errno


struct stat {

               dev_t     st_dev;     /* ID of device containing file */

               ino_t     st_ino;     /* inode number */

               mode_t    st_mode;    /* S_ISREG(st_mode)  是一个普通文件  S_ISDIR(st_mode)  是一个目录*/   

               nlink_t   st_nlink;   /* number of hard links */

               uid_t     st_uid;     /* user ID of owner */

               gid_t     st_gid;     /* group ID of owner */

               dev_t     st_rdev;    /* device ID (if special file) */

               off_t     st_size;    /* total size, in bytes */

               blksize_t st_blksize; /* blocksize for filesystem I/O */

               blkcnt_t  st_blocks;  /* number of 512B blocks allocated */

               time_t    st_atime;   /* time of last access */

               time_t    st_mtime;   /* time of last modification */

               time_t    st_ctime;   /* time of last status change */

           };


当前阶段完整代码实现

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <ctype.h>
#include <arpa/inet.h>
#include <errno.h>
#include <sys/stat.h>
#include <unistd.h>




#define SERVER_PORT 80

static int debug = 1;

int get_line(int sock, char *buf, int size);
void do_http_request(int client_sock);
void do_http_response(int client_sock, const char *path);
int  headers(int client_sock, FILE *resource);
void cat(int client_sock, FILE *resource);

void not_found(int client_sock);
void inner_error(int client_sock);

int main(void){

    int sock;//代表信箱
    struct sockaddr_in server_addr;


    //1.美女创建信箱
    sock = socket(AF_INET, SOCK_STREAM, 0);

    //2.清空标签,写上地址和端口号
    bzero(&server_addr, sizeof(server_addr));
    server_addr.sin_family = AF_INET;//选择协议族IPV4
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);//监听本地所有IP地址
    server_addr.sin_port = htons(SERVER_PORT);//绑定端口号

      //实现标签贴到收信得信箱上
    bind(sock, (struct sockaddr *)&server_addr,  sizeof(server_addr));

    //把信箱挂置到传达室,这样,就可以接收信件了
    listen(sock, 128);

    //万事俱备,只等来信
    printf("等待客户端的连接\n");


    int done =1;

    while(done){
        struct sockaddr_in client;
        int client_sock, len, i;
        char client_ip[64];
        char buf[256];

        socklen_t  client_addr_len;
        client_addr_len = sizeof(client);
        client_sock = accept(sock, (struct sockaddr *)&client, &client_addr_len);

        //打印客服端IP地址和端口号
        printf("client ip: %s\t port : %d\n",
                 inet_ntop(AF_INET, &client.sin_addr.s_addr,client_ip,sizeof(client_ip)),
                 ntohs(client.sin_port));
        /*处理http 请求,读取客户端发送的数据*/
        do_http_request(client_sock);
		close(client_sock);

    }
    close(sock);
    return 0;
}


void do_http_request(int client_sock){
	int len = 0;
	char buf[256];
	char method[64];
	char url[256];
	char path[256];
	
	struct stat  st;
	
	
	/*读取客户端发送的http 请求*/
	
	
	//1.读取请求行
	len = get_line(client_sock, buf, sizeof(buf));
	
	if(len > 0){//读到了请求行
		int i=0, j=0;
		while(!isspace(buf[j]) && (i<sizeof(method)-1)){
			method[i] = buf[j];
			i++;
			j++;
		}
		
		method[i] = '\0';
		if(debug) printf("request method: %s\n", method);
		
		if(strncasecmp(method, "GET", i)==0){ //只处理get请求
	        if(debug) printf("method = GET\n
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值