HTTP连接(读取请求+解析请求+生成响应+回送响应)
创始人
2024-05-11 00:23:00
0

一个HTTP连接的功能就是:读取请求+解析请求+生成响应+回送响应

解析HTTP请求报文(GET、POST)完成了读取请求+解析请求的两步;

生成HTTP响应报文 完成了生成响应的一步;

所以本文首先要实现回送响应的部分,然后将这四步有序组织起来。

首先是回送响应:

因为生成请求的部分将响应头置于缓冲区buffer内,将响应体即要回送的文件,通过mmap方式建立了内存映射,获得一个指向被映射区的指针char* mmFile。

通过writev方法,将两块内存中的数据集中写至socket中,发往客户端

  1. 给struct iovec vec[2] 赋值,vec[0]保存响应头的首地址和长度,vec[1]保存响应体的首地址和长度

    response.makeResponse(writeBuff);//响应头vec[0].iov_base=const_cast(writeBuff.peek());vec[0].iov_len=writeBuff.readableBytes();iovCnt=1;//响应体if(response.getFileLen()>0&&response.getfile()){vec[1].iov_base=response.getfile();vec[1].iov_len=response.getFileLen();iovCnt=2;}
  1. 使用writev函数向socket内写入响应报文

ssize_t HttpConn::write(int* errno_)
{ssize_t len=-1;while (true){len=writev(fd,vec,iovCnt);if(len<0)//出错{*errno_=errno;break;}if(vec[0].iov_len+vec[1].iov_len==0)//全部写完 { break; }if(static_cast(len)>vec[0].iov_len){vec[1].iov_base=(uint8_t*)vec[1].iov_base+(len-vec[0].iov_len);vec[1].iov_len-=(len-vec[0].iov_len);if(vec[0].iov_len){writeBuff.retrieveAll();vec[0].iov_len=0;}}else{vec[0].iov_base=(uint8_t*)vec[0].iov_base+len;vec[0].iov_len-=len;writeBuff.retrieve(len);}}return len;   
}

其次是组织读取请求+解析请求+生成响应+回送响应这四步:

通过ssize_t HttpConn::read(int* errno_) +bool HttpConn::process()函数+上面的ssize_t HttpConn::write(int* errno_)函数完成。

/*从客户端读取请求至readBuff内*/
ssize_t HttpConn::read(int* errno_)
{ssize_t len=-1;while(true){len=readBuff.readFd(fd,errno_);if(len<=0)break;}return len;
}
/*解析客户端请求,生成Http响应报文*/
bool HttpConn::process()
{request.init();//初始化Http请求if(readBuff.readableBytes()<=0){return false;}if(request.parse(readBuff))//解析Http请求成功{LOG_DEBUG("%s", request.getPath().c_str());//初始化Http响应,状态码为200response.init(srcDir,request.getPath(),request.isKeepAlive(),200);}else//解析Http请求失败{//初始化Http响应,状态码为400response.init(srcDir,request.getPath(),false,400);}response.makeResponse(writeBuff);//生成Http响应报文/*给struct iovec vec[2]赋值,vec[0]保存响应头的首地址和长度,vec[1]保存响应体的首地址和长度*///响应头vec[0].iov_base=const_cast(writeBuff.peek());vec[0].iov_len=writeBuff.readableBytes();iovCnt=1;//响应体if(response.getFileLen()>0&&response.getfile()){vec[1].iov_base=response.getfile();vec[1].iov_len=response.getFileLen();iovCnt=2;}return true;
}

HttpConn类结构 httpconn.h

#ifndef HTTPCONN_H
#define HTTPCONN_H#include
#include
#include #include "../log/log.h"
#include "../pool/sqlconnpool.h"
#include "../buffer/buffer.h"
#include "httprequest.h"
#include "httpresponse.h"class HttpConn
{
public:HttpConn();~HttpConn();void init(int connfd,const sockaddr_in& sockAddr);ssize_t read(int* errno_);//从客户端读取请求bool process();//解析请求+生成响应ssize_t write(int* errno_);//向客户端写响应void closeConn();//关闭Http连接const sockaddr_in& getSockAddr() const;int getFd() const;int getPort() const;const char* getIP() const;bool isKeepAlive() const;bool isWriteOver() const;static std::atomic userCount;//原子类型,保证多线程修改userCount时的正确性static const char* srcDir;
private:int fd;struct sockaddr_in addr;bool isClose;int iovCnt;struct  iovec vec[2];Buffer readBuff;Buffer writeBuff;HttpRequest request;HttpResponse response;
};#endif //! HTTPCONN__H

HttpConn类实现 httpconn.cpp

#include "httpconn.h"std::atomic HttpConn::userCount;
const char* HttpConn::srcDir=nullptr;HttpConn::HttpConn()
{fd=-1;addr={0};isClose=true;Log::getInstance()->init();
}HttpConn::~HttpConn()
{closeConn();
}void HttpConn::closeConn()
{response.unmapFile();if(isClose==false){isClose=true;userCount--;close(fd);LOG_INFO("Client (%s:%d) quit, userCount:%d",getIP(),getPort(),static_cast(userCount));}
}void HttpConn::init(int connfd,const sockaddr_in& sockAddr)
{assert(connfd>0);userCount++;fd=connfd;addr=sockAddr;readBuff.retrieveAll();writeBuff.retrieveAll();isClose=false;LOG_INFO("Client (%s:%d) in, userCount:%d",getIP(),getPort(),static_cast(userCount));
}const sockaddr_in& HttpConn::getSockAddr() const
{return addr;
}
int HttpConn::getFd() const
{return fd;
}
int HttpConn::getPort() const
{return addr.sin_port;
}
const char* HttpConn::getIP() const
{return inet_ntoa(addr.sin_addr);
}
bool HttpConn::isKeepAlive() const
{return request.isKeepAlive();
}
bool HttpConn::isWriteOver() const
{return vec[0].iov_len+vec[1].iov_len==0;
}ssize_t HttpConn::read(int* errno_)
{ssize_t len=-1;while(true){len=readBuff.readFd(fd,errno_);if(len<=0)break;}return len;
}ssize_t HttpConn::write(int* errno_)
{ssize_t len=-1;while (true){len=writev(fd,vec,iovCnt);if(len<0){*errno_=errno;break;}if(vec[0].iov_len+vec[1].iov_len==0) { break; }if(static_cast(len)>vec[0].iov_len){vec[1].iov_base=(uint8_t*)vec[1].iov_base+(len-vec[0].iov_len);vec[1].iov_len-=(len-vec[0].iov_len);if(vec[0].iov_len){writeBuff.retrieveAll();vec[0].iov_len=0;}}else{vec[0].iov_base=(uint8_t*)vec[0].iov_base+len;vec[0].iov_len-=len;writeBuff.retrieve(len);}}return len;   
}bool HttpConn::process()
{request.init();if(readBuff.readableBytes()<=0){return false;}if(request.parse(readBuff)){LOG_DEBUG("%s", request.getPath().c_str());response.init(srcDir,request.getPath(),request.isKeepAlive(),200);}else{response.init(srcDir,request.getPath(),false,400);}response.makeResponse(writeBuff);//响应头vec[0].iov_base=const_cast(writeBuff.peek());vec[0].iov_len=writeBuff.readableBytes();iovCnt=1;//响应体if(response.getFileLen()>0&&response.getfile()){vec[1].iov_base=response.getfile();vec[1].iov_len=response.getFileLen();iovCnt=2;}return true;
}

相关内容

热门资讯

中考加油作文(实用6篇) 中考加油作文 篇一中考加油作文近日,我即将迎来人生中的重要一刻——中考。在这漫长的三年中,我付出了大...
就这样,埋下一颗种子中考作文... 就这样,埋下一颗种子中考作文篇一随着时间的推移,中考的脚步越来越近,我感受到了胸口的紧迫感。这次中考...
青春与爱同行中考范文(精选6... 青春与爱同行中考范文 篇一初中生活即将结束,我对这段时光充满了感慨和思考。回想起这三年来的点点滴滴,...
太阳作文(精选3篇) 太阳作文 篇一太阳,这是我们熟悉的天体之一。它是地球的中心,为我们提供了光和热,使我们能够生存。太阳...
中考大山(通用3篇) 中考大山 篇一大山,是我心中最美的地方。每当我想起中考时的那个夏天,总会想起我和同学们一起攀登大山的...
中考文言文必考篇目重点翻译句... 篇一:中考文言文必考篇目重点翻译句子文言文作为中考必考的一项内容,对学生的翻译能力要求较高。下面是几...
中考语文考试重点分析范文【精... 中考语文考试重点分析范文 篇一中考语文考试重点分析范文语文考试一直是中考中最重要的科目之一,它不仅考...
中考英语词语辨析:alive... 中考英语词语辨析:alive/ living/ the living/ 篇一标题:The Diffe...
中考热点作文【经典6篇】 中考热点作文 篇一题目:网络游戏对青少年的影响随着互联网的普及和技术的进步,网络游戏已经成为了许多青...
中考满分作文范文欣赏(精彩6... 中考满分作文范文欣赏 篇一梦想的力量人生如同一场马拉松,我们需要不断努力奔跑,才能到达胜利的终点。而...
中考作文写事满分范文(实用6... 中考作文写事满分范文 篇一我与“长者的故事”近日,我有幸参加了一次与老人们交流的活动,这让我对长者们...
你是我的太阳中考优秀作文【精... 你是我的太阳中考优秀作文 篇一太阳是地球上最重要的存在,它给予了我们光明与温暖。然而,在我心中,你是...
中考优秀作文满分范文大全【最... 中考优秀作文满分范文大全 篇一题目: 足球与我足球是一项广受欢迎的体育运动,也是我生活中不可或缺的一...
山西中考语文作文模板范文(推... 山西中考语文作文模板范文 篇一标题:传统与现代的碰撞随着社会的发展,传统文化与现代社会产生了许多碰撞...
“大爱”中考满分作文点评(精... “大爱”中考满分作文点评 篇一第一篇内容:探讨大爱的意义和体现方式在我们的日常生活中,大爱无处不在。...
中考辅导:语文知识复习(精彩... 中考辅导:语文知识复习 篇一语文知识复习对于中考来说是至关重要的。通过对重点知识的复习和巩固,可以提...
中考命题特点分析报告范文【优... 中考命题特点分析报告范文 篇一中考命题特点分析报告近年来,中考命题在内容和形式上都呈现出一些特点。本...
广西南宁中考作文题目专家点评... 广西南宁中考作文题目专家点评 篇一题目:如何提高中学生的阅读能力?中学生的阅读能力是一个重要的学习能...
考试后感想作文(精彩6篇) 考试后感想作文 篇一我对这次考试的感想这次考试结束了,我心情非常复杂。虽然我付出了很多努力,但结果并...
中考满分作文大全【优秀3篇】 中考满分作文大全 篇一健康饮食的重要性现代社会,随着生活水平的提高和生活节奏的加快,人们的饮食习惯也...