基于多反应堆的高并发服务器【C/C++/Reactor】(中)HttpResponse的定义和初始化 以及组织 HttpResponse 响应消息

一、HttpResponse的定义

1.定义状态码枚举

// 定义状态码枚举
enum HttpStatusCode {Unknown = 0,OK = 200,MovedPermanently = 301,MovedTemporarily = 302,BadRequest = 400,NotFound = 404
};

2.HTTP 响应报文格式

 这个数据块主要是分为四部分

  1. 第一部分是状态行
  2. 第二部分是响应头
  3. 第三部分是一个空行
  4. 第四部分是给客户端回复的数据块
// 定义响应的结构体
struct ResponseHeader {char key[32];char value[128];
};// 定义一个函数指针,用来组织要回复给客户端的数据块
typedef void (*responseBody) (const char* fileName,struct Buffer* sendBuf,int socket);// 定义结构体
struct HttpResponse {// 状态行:状态码,状态描述enum HttpStatusCode statusCode;char statusMsg[128];// 响应头 - 键值对struct ResponseHeader* headers;int headerNum;responseBody sendDataFunc;// 文件名char fileName[128];
};

服务器回复给客户端的数据,取决于客户端向服务器请求了什么类型的资源,有可能它请求的是一个目录,有可能请求的是一个文件,这个文件有可能是一个文本文件,也可能是一个图片,还可能是mp3...需要根据客户端的请求去回复相应的数据。所以如何去组织这个需要回复的数据块呢?

// 定义一个函数指针,用来组织要回复给客户端的数据块
typedef void (*responseBody) (const char* fileName,struct Buffer* sendBuf,int socket);

fileName:分成两类,一类是目录类型,类是非目录类型的文件

  • 如果是目录,就去遍历目录
  • 如果是文件,就读取其内容

sendBuf:在进行套接字的通信过程中:

  • 如果要回复数据(给客户端发数据),发送的数据要先存储到sendBuf里边,再发送给客户端.

socket:就是用来通信的文件描述符,通过这个用于通信的文件描述符,就能够把写入到sendBuf里边的数据发送给客户端,sendBuf里边的数据就是我们组织好的Http响应的数据块

  • 定义一个函数指针,用来组织要回复给客户端的数据块
responseBody sendDataFunc;

二、HttpResponse的初始化

// 初始化
struct HttpResponse* httpResponseInit();
#define ResHeaderSize 16
// 初始化
struct HttpResponse* httpResponseInit() {struct HttpResponse* response = (struct HttpResponse*)malloc(sizeof(struct HttpResponse));// 状态行:状态码,状态描述response->statusCode = Unknown;bzero(response->statusMsg,sizeof(response->statusMsg));// 响应头 - 键值对int size = sizeof(struct ResponseHeader) * ResHeaderSize;response->headers = (struct ResponseHeader*)malloc(size);bzero(response->headers, size);response->headerNum = 0;// 函数指针response->sendDataFunc = NULL;// 文件名bzero(response->fileName,sizeof(response->fileName));return response;
}

三、HttpResponse的销毁 内存释放

// 销毁
void httpResponseDestroy(struct HttpResponse* response);
// 销毁
void httpResponseDestroy(struct HttpResponse* response) {if(response!=NULL) {free(response->headers);free(response);}
}

四、添加响应头

// 添加响应头
void httpResponseAddHeader(struct HttpResponse* response,const char* key,const char* value);
// 添加响应头
void httpResponseAddHeader(struct HttpResponse* response,const char* key,const char* value){if(response == NULL || key == NULL || value == NULL) {return;}strcpy(response->headers[response->headerNum].key,key);strcpy(response->headers[response->headerNum].value,value);response->headerNum++;
}

五、组织http响应数据

// 组织http响应数据
void httpResponsePrepareMsg(struct HttpResponse* response,struct Buffer* sendBuf,int socket);
// 组织http响应数据
void httpResponsePrepareMsg(struct HttpResponse* response,struct Buffer* sendBuf,int socket) {// 状态行char tmp[1024] = {0};sprintf(tmp,"HTTP/1.1 %d %s\r\n",response->statusCode,response->statusMsg);bufferAppendString(sendBuf,tmp);// 响应头for(int i=0;i<response->headerNum;++i) {// memset(tmp,0,sizeof(tmp));  ?????????sprintf(tmp,"%s: %s\r\n",response->headers[i].key,response->headers[i].value);bufferAppendString(sendBuf,tmp);}// 空行bufferAppendString(sendBuf,"\r\n");// 回复的数据response->sendDataFunc(response->fileName,sendBuf,socket);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/607017.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Hyperledger Fabric 管理链码 peer lifecycle chaincode 指令使用

链上代码&#xff08;Chaincode&#xff09;简称链码&#xff0c;包括系统链码和用户链码。系统链码&#xff08;System Chaincode&#xff09;指的是 Fabric Peer 中负责系统配置、查询、背书、验证等平台功能的代码逻辑&#xff0c;运行在 Peer 进程内&#xff0c;将在第 14 …

【嵌入式-网络编程】vmware中使用UDP广播失败问题

问题描述&#xff1a; 自己在vmware中搭建了2台虚拟机&#xff0c;虚拟机A向虚拟机A和虚拟机B发送广播信息&#xff0c;接收端在虚拟机A和虚拟机B&#xff0c;这个时候&#xff0c;由于没配置sin.sin_addr.s_addr htonl(INADDR_ANY);&#xff0c;而是配置的inet_pton(AF_INET,…

基于多反应堆的高并发服务器【C/C++/Reactor】(中)HttpRequest模块 解析http请求协议

一、HTTP响应报文格式 HTTP/1.1 200 OK Bdpagetype: 1 Bdqid: 0xf3c9743300024ee4 Cache-Control: private Connection: keep-alive Content-Encoding: gzip Content-Type: text/html;charsetutf-8 Date: Fri, 26 Feb 2021 08:44:35 GMT Expires: Fri, 26 Feb 2021 08:44:35 GM…

今日实践 — 附加数据库/重定向失败如何解决?

WMS数据库与重定向 前言正文如何建立数据库连接&#xff1f;第一步&#xff1a;打开SSMS&#xff0c;右击数据库&#xff0c;点击附加第二步&#xff1a;点击添加第三步&#xff1a;找到自己的数据库文件&#xff0c;点击确定按钮第四步&#xff1a;若有多个数据库&#xff0c;…

如何使用静态IP代理解决Facebook多账号注册并进行网络推广业务?

在当今的数字时代&#xff0c;社交媒体成为了企业进行网络推广的一个重要途径&#xff0c;其中&#xff0c;Facebook是最受欢迎的社交媒体之一&#xff0c;因为它可以让企业通过创建广告和页面来推广他们的产品或服务。 但是&#xff0c;使用Facebook进行网络推广时&#xff0…

Spring Cloud GateWay实现熔断降级

熔断降级 当分布式系统中的网关接收到大量请求并向后端远程系统或服务发起调用时&#xff0c;后端服务可能会产生调用失败&#xff08;如超时或异常&#xff09;。这时&#xff0c;如果让请求继续堆积在网关上&#xff0c;可能会导致整个系统的瘫痪。因此&#xff0c;需要快速…

React16源码: React中Fiber对象的源码实现

关于 Fiber 对象 在FiberRoot里面&#xff0c;它也会为我们去创建的一个对象叫做 Fiber在 React16 之后, 非常核心&#xff0c;非常重要的一个东西A. 每个 ReactElement 都会对应一个 Fiber 对象B. 它会记录节点的各种状态 比如&#xff0c;class component&#xff0c;它的st…

面试算法101:分割等和子集

题目 给定一个非空的正整数数组&#xff0c;请判断能否将这些数字分成和相等的两部分。例如&#xff0c;如果输入数组为[3&#xff0c;4&#xff0c;1]&#xff0c;将这些数字分成[3&#xff0c;1]和[4]两部分&#xff0c;它们的和相等&#xff0c;因此输出true&#xff1b;如…

Docker 中使用超级用户

在docker中安装keytool产生的问题&#xff1a; sudo apt-get install openjdk-8-jre-headless bash: sudo: command not found elasticsearchd989639e3cb4:~/config/certs$ apt-get install openjdk-8-jre-headless E: Could not open lock file /var/lib/dpkg/lock-frontend …

【代码复现系列】paper:CycleGAN and pix2pix in PyTorch

或许有冗余步骤、之后再优化。 1.桌面右键-git bash-输入命令如下【git clone https://github.com/junyanz/pytorch-CycleGAN-and-pix2pix】 2.打开anaconda的prompt&#xff0c;cd到pytorch-CycleGAN-and-pix2pix路径 3.在prompt里输入【conda env create -f environment.y…

【数值分析】逼近,正交多项式

逼近 由离散点&#xff08;函数表&#xff09;给出函数关系通常有两种方法&#xff1a; 使用多项式插值 使用多项式插值会带来两个问题&#xff1a;1. 龙格现象2. 数值本身带有误差&#xff0c;使用插值条件来确定函数关系不合理三次样条插值 三次样条插值克服了龙格现象&…

多线程在编程中的重要性有什么?并以LabVIEW为例进行说明

多线程在编程中的重要性体现在以下几个方面&#xff1a; 并行处理&#xff1a; 多线程允许程序同时执行多个任务&#xff0c;这在现代多核心处理器上尤其重要。通过并行处理&#xff0c;可以显著提高程序的执行效率和响应速度。 资源利用最大化&#xff1a; 通过多线程&#x…

工厂设计模式的思考

工厂模式对于开发者来说并不陌生&#xff0c;他利用多肽性很好的进行业务之间的解耦&#xff0c;不同的场景创建不同的实现&#xff0c;从而使得更多的关注业务实现,这种简单的实现这里不在举例。但是如果情形比较多的时候就会遇到问题&#xff0c;我们的工厂类就会产生大量的i…

Nacos与Eureka的区别详解

Nacos与Eureka的区别详解 在微服务架构中,服务注册与发现是核心组件之一,它们允许服务实例在启动时自动注册,并且能被其他服务发现,从而实现服务之间的互相通信。Nacos和Eureka都是现代微服务体系中广泛使用的服务注册与发现工具。本文将深入分析二者的区别,并为您提供一…

基于YOLOv7开发构建道路交通场景下CCTSDB2021交通标识检测识别系统

交通标志检测是交通标志识别系统中的一项重要任务。与其他国家的交通标志相比&#xff0c;中国的交通标志有其独特的特点。卷积神经网络&#xff08;CNN&#xff09;在计算机视觉任务中取得了突破性进展&#xff0c;在交通标志分类方面取得了巨大的成功。CCTSDB 数据集是由长沙…

OpenFeign超时控制

OpenFeign超时控制 前面简单介绍了Feign和OpenFeign的关系&#xff0c;言归正传&#xff0c;接下来我们看看OpenFeign如何设置调用超时&#xff0c;openFeign其实是有默认的超时时间的&#xff0c;默认分别是连接超时时间10秒、读超时时间60秒&#xff0c;源码在feign.Request…

Elasticsearch中object类型与nested类型以及数组之间的区别

一、区别&#xff1a; 0、一般情况下用object 类型来查es中为json对象的字段数据&#xff0c;用nested来查es中为JsonArray数组类型的字段数据。 1、默认情况下ES会把JSON对象直接映射为object类型&#xff0c;只有手动设置才会映射为nested类型 2、object类型可以直接使用普…

十九:爬虫最终篇-平安银行商城实战

平安银行商场实战 需求 获取该商城商品信息 目标网址 https://m.yqb.com/bank/product-item-50301196.html?mcId1583912328849970&loginModepab&historyy&sceneModem&traceid30187_4dXJVel1iop详细步骤 1、寻找数据接口 2、对比payload寻找可疑参数 3、多…

Day28 回溯算法part04 93. 复原IP地址 78. 子集 90. 子集 II

回溯算法part04 93. 复原IP地址 78. 子集 90. 子集 II 93. 复原 IP 地址 class Solution { private:vector<string> result;bool isValid(string& s,int start,int end){if (start > end) return false;if (s[start] 0 && start ! end) { // 0开头的数…

图像融合论文阅读:CrossFuse: 一种基于交叉注意机制的红外与可见光图像融合方法

article{li2024crossfuse, title{CrossFuse: A novel cross attention mechanism based infrared and visible image fusion approach}, author{Li, Hui and Wu, Xiao-Jun}, journal{Information Fusion}, volume{103}, pages{102147}, year{2024}, publisher{Elsevier} } 论文…