系统相关
首页 > 系统相关> > linux服务器HTTP协议内容、实现程序代码

linux服务器HTTP协议内容、实现程序代码

作者:互联网

http协议

1. http简介

http协议叫做超文本传输协议。

2.http工作原理

3.http请求响应过程

例子:URL:http://www.example.com/filepath/index.html

  1. DNS服务器会对浏览器上输入的域名进行映射,先找到http://www.example.com的地址,http客户端会在80端口发起一个到服务器http://www.example.comTCP连接,发送请求报文,报文内容包括对filepath/index.html的请求。
  2. http服务器接受连接和请求,解析报文并检索出对象filepath/index.html,然后从从磁盘或内存中取出数据进行http报文封装并回发,发完就断开连接。
  3. 客户端接收到数据后,也断开连接,并从报文中取出资源文件。

4.http协议特点

5.客户端请求报文

如图,报文:请求方法+请求头部+请求数据。
请求报文

6.服务器响应报文

如图,报文:状态行+消息报头+空行+响应正文
响应例如例子

7.http的优点和缺点

1. 优点

2. 缺点

3.性能

程序实现

这里程序使用epoll反应堆模型作为框架实现,reactor内容可以在我的博客里面查看。如果单纯想看了解http协议可以前往我主页查看另一篇博客关于tinyhttp开源项目。

下面是用epoll反应堆reactor(C1000K)模型下实现http服务器的介绍~

基于reactor模型的HTTP服务器

客户端结构体

struct qsevent{
    int fd;				//clientfd
    int events;			//事件:读、写或异常
    int status;			//是否位于epfd红黑监听树上
    void *arg;			//参数
    long last_active;	//上次数据收发的事件

    int (*callback)(int fd, int event, void *arg);	//回调函数,单回调,后面修改成多回调
    unsigned char buffer[MAX_BUFLEN];				//数据缓冲区
    int length;										//数据长度

    /*http param*/
    int method;						//http协议请求头部
    char resource[MAX_BUFLEN];		//请求的资源
    int ret_code;					//响应状态码
};

int http_response(struct qsevent *ev)

当客户端发送tcp连接时,服务端的listenfd会触发输入事件会调用ev->callback即accept_cb回调函数响应连接并获得clientfd,连接之后,http数据报文发送上来,服务端的clientfd触发输入事件会调用ev->callback即recv_cb回调函数进行数据接收,并解析http报文。

int http_request(struct qsevent *ev)
{
    char linebuf[1024] = {0};//用于从buffer中获取每一行的请求报文
    int idx = readline(ev->buffer, 0, linebuf);//读取第一行请求方法,readline函数,后面介绍
    if(strstr(linebuf, "GET"))//strstr判断是否存在GET请求方法
    {
        ev->method = HTTP_METHOD_GET;//GET方法表示客户端需要获取资源

        int i = 0;
        while(linebuf[sizeof("GET ") + i] != ' ')i++;//跳过空格
        linebuf[sizeof("GET ") + i] = '\0';
        sprintf(ev->resource, "./%s/%s", HTTP_METHOD_ROOT, linebuf+sizeof("GET "));//将资源的名字以文件路径形式存储在ev->resource中
        printf("resource:%s\n", ev->resource);//回显
    }
    else if(strstr(linebuf, "POST"))//POST的请求方法,暂时没写,方法差不多
    {}
    return 0;
}

int http_response(struct qsevent *ev)

服务器对客户端的响应报文数据进行http封装储存在buffer中,事件触发时在send_cb回调函数发送给客户端。详细解释请看代码注释。

int http_response(struct qsevent *ev)
{
    if(ev == NULL)return -1;
    memset(ev->buffer, 0, MAX_BUFLEN);//清空缓冲区准备储存报文

    printf("resource:%s\n", ev->resource);//resource:客户端请求的资源文件,通过http_reques函数获取
    int filefd = open(ev->resource, O_RDONLY);//只读方式打开获得文件句柄
    if(filefd == -1)//获取失败则发送404 NOT FOUND
    {
        ev->ret_code = 404;//404状态码
        ev->length = sprintf(ev->buffer,//将下面数据传入ev->buffer
        					 /***状态行***/
        					 /*版本号 状态码 状态码描述 */
                             "HTTP/1.1 404 NOT FOUND\r\n"
                             /***消息报头***/
                             /*获取当前时间*/
                             "date: Thu, 11 Nov 2021 12:28:52 GMT\r\n"
                             /*响应正文类型;              编码方式*/
                             "Content-Type: text/html;charset=ISO-8859-1\r\n"
                             /*响应正文长度          空行*/
                             "Content-Length: 85\r\n\r\n"
                             /***响应正文***/
                             "<html><head><title>404 Not Found</title></head><body><H1>404</H1></body></html>\r\n\r\n");
    }
    else 
    {
        struct stat stat_buf;			//文件信息
        fstat(filefd, &stat_buf);		//fstat通过文件句柄获取文件信息
        if(S_ISDIR(stat_buf.st_mode))	//如果文件是一个目录
        {

            printf(ev->buffer, //同上,将404放入buffer中
                   "HTTP/1.1 404 Not Found\r\n"
                   "Date: Thu, 11 Nov 2021 12:28:52 GMT\r\n"
                   "Content-Type: text/html;charset=ISO-8859-1\r\n"
                   "Content-Length: 85\r\n\r\n"
                   "<html><head><title>404 Not Found</title></head><body><H1>404</H1></body></html>\r\n\r\n" );

        } 
        else if (S_ISREG(stat_buf.st_mode)) //如果文件是存在
        {

            ev->ret_code = 200;		//200状态码

            ev->length = sprintf(ev->buffer, //length记录长度,buffer储存响应报文
                                 "HTTP/1.1 200 OK\r\n"
                                 "Date: Thu, 11 Nov 2021 12:28:52 GMT\r\n"
                                 "Content-Type: text/html;charset=ISO-8859-1\r\n"
                                 "Content-Length: %ld\r\n\r\n", 
                                 stat_buf.st_size );//文件长度储存在stat_buf.st_size中

        }
        return ev->length;//返回报文长度
    }
}

git clone代码

自行git clone git clone https://github.com/qiushii/reactor.git

标签:http,请求,int,报文,linux,HTTP,ev,程序代码,客户端
来源: https://blog.csdn.net/yuqiushiya/article/details/121802368