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

本文主要是介绍基于多反应堆的高并发服务器【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);
}

这篇关于基于多反应堆的高并发服务器【C/C++/Reactor】(中)HttpResponse的定义和初始化 以及组织 HttpResponse 响应消息的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


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

相关文章

C/C++ chrono简单使用场景示例详解

《C/C++chrono简单使用场景示例详解》:本文主要介绍C/C++chrono简单使用场景示例详解,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友... 目录chrono使用场景举例1 输出格式化字符串chrono使用场景China编程举例1 输出格式化字符串示

C++/类与对象/默认成员函数@构造函数的用法

《C++/类与对象/默认成员函数@构造函数的用法》:本文主要介绍C++/类与对象/默认成员函数@构造函数的用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录名词概念默认成员函数构造函数概念函数特征显示构造函数隐式构造函数总结名词概念默认构造函数:不用传参就可以

C++类和对象之默认成员函数的使用解读

《C++类和对象之默认成员函数的使用解读》:本文主要介绍C++类和对象之默认成员函数的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、默认成员函数有哪些二、各默认成员函数详解默认构造函数析构函数拷贝构造函数拷贝赋值运算符三、默认成员函数的注意事项总结一

C/C++中OpenCV 矩阵运算的实现

《C/C++中OpenCV矩阵运算的实现》本文主要介绍了C/C++中OpenCV矩阵运算的实现,包括基本算术运算(标量与矩阵)、矩阵乘法、转置、逆矩阵、行列式、迹、范数等操作,感兴趣的可以了解一下... 目录矩阵的创建与初始化创建矩阵访问矩阵元素基本的算术运算 ➕➖✖️➗矩阵与标量运算矩阵与矩阵运算 (逐元

C/C++的OpenCV 进行图像梯度提取的几种实现

《C/C++的OpenCV进行图像梯度提取的几种实现》本文主要介绍了C/C++的OpenCV进行图像梯度提取的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录预www.chinasem.cn备知识1. 图像加载与预处理2. Sobel 算子计算 X 和 Y

C/C++和OpenCV实现调用摄像头

《C/C++和OpenCV实现调用摄像头》本文主要介绍了C/C++和OpenCV实现调用摄像头,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录准备工作1. 打开摄像头2. 读取视频帧3. 显示视频帧4. 释放资源5. 获取和设置摄像头属性

c/c++的opencv图像金字塔缩放实现

《c/c++的opencv图像金字塔缩放实现》本文主要介绍了c/c++的opencv图像金字塔缩放实现,通过对原始图像进行连续的下采样或上采样操作,生成一系列不同分辨率的图像,具有一定的参考价值,感兴... 目录图像金字塔简介图像下采样 (cv::pyrDown)图像上采样 (cv::pyrUp)C++ O

c/c++的opencv实现图片膨胀

《c/c++的opencv实现图片膨胀》图像膨胀是形态学操作,通过结构元素扩张亮区填充孔洞、连接断开部分、加粗物体,OpenCV的cv::dilate函数实现该操作,本文就来介绍一下opencv图片... 目录什么是图像膨胀?结构元素 (KerChina编程nel)OpenCV 中的 cv::dilate() 函

C++ RabbitMq消息队列组件详解

《C++RabbitMq消息队列组件详解》:本文主要介绍C++RabbitMq消息队列组件的相关知识,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. RabbitMq介绍2. 安装RabbitMQ3. 安装 RabbitMQ 的 C++客户端库4. A

python多线程并发测试过程

《python多线程并发测试过程》:本文主要介绍python多线程并发测试过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、并发与并行?二、同步与异步的概念?三、线程与进程的区别?需求1:多线程执行不同任务需求2:多线程执行相同任务总结一、并发与并行?1、