基于多反应堆的高并发服务器【C/C++/Reactor】(中)HtttpRequest的定义和初始化、资源重置和销毁
2024-01-08 17:52:05
一、Get方式提交数据
如果使用get的方式向服务器提交数据,数据并没有在请求协议的第四部分,而是在请求行的第二部分。如果使用get方式提交数据,第四部分是空的
这是浏览器对用户的请求数据进行了封装之后,得到的原始的http请求数据
>>http get请求报文的格式
请求行\r\n
请求头\r\n
空行(\r\n)
提示: 每项信息之间都需要一个\r\n,是由http协议规定
************************************************
************************************************
>>http post请求报文的格式
请求行\r\n
请求头\r\n
空行(\r\n)
请求体
提示: 请求体就是浏览器发送给服务器的数据
在HTTP报文中,每一行的数据有\r\n作为结束字符,空行则是仅仅是字符\r\n。因此,可以通过查找\r\n将报文拆解成单独的行进行解析,项目中便是利用了这一点。?
?(一)HtttpRequest的定义
// 请求头键值对
struct RequestHeader{
char* key;
char* value;
};
// 当前的解析状态
enum HttpRequestState {
ParseReqLine, // 当前解析的是请求行
ParseReqHeaders, // 当前解析的是请求头
ParseReqBody, // 当前解析的是请求体
ParseReqDone // 完成解析
};
// 定义 http 请求结构体
struct HttpRequest {
// 当前解析状态
enum HttpRequestState curState;
// 请求行
char* method;
char* url;
char* version;
// 请求头
struct RequestHeader* reqHeaders;
int reqHeadersNum;
};
(二)初始化
// 初始化
struct HttpRequest* httpRequestInit();
struct HttpRequest* httpRequestInit() {
struct HttpRequest* request = (struct HttpRequest*)malloc(sizeof(struct HttpRequest));
request->curState = ParseReqLine;
// 请求行
request->method = NULL;
request->url = NULL;
request->version = NULL;
// 请求头
request->reqHeaders = (struct RequestHeader*)malloc(sizeof(struct RequestHeader) * HeaderSize);
request->reqHeadersNum = 0;
return request;
}
(三)初始化、资源重置
资源重置:当一个浏览器和服务器建立连接之后,浏览器给服务器发送数据,服务器接收到浏览器的请求消息之后,就需要进行解析了。解析之后的数据存储到HttpRequest结构体里边,对于method,url,version它们是指针,其实是需要指向一块有效的内存的。再给这个指针赋值的时候,需要先malloc一块内存,再让指针指向这块内存。如果这个浏览器和服务器建立连接之后,它们进行了多次通信,那么就需要多次往HttpRequest结构体里边写数据,第一次写的时候,method对应一块堆内存。那么再次写入,需要把上次写入的数据清除掉,由于清除的是堆内存,可以用free函数?(防止内存泄漏)
// 初始化
struct HttpRequest* httpRequestInit();
// 重置
void httpRequestReset(struct HttpRequest* req);
void httpRequestResetEx(struct HttpRequest* req);
// 初始化
struct HttpRequest* httpRequestInit() {
struct HttpRequest* request = (struct HttpRequest*)malloc(sizeof(struct HttpRequest));
httpRequestReset(request);
request->reqHeaders = (struct RequestHeader*)malloc(sizeof(struct RequestHeader) * HeaderSize);
return request;
}
// 重置
void httpRequestReset(struct HttpRequest* req) {
req->curState = ParseReqLine;
req->method = NULL;
req->url = NULL;
req->version = NULL;
req->reqHeadersNum = 0;
}
void httpRequestResetEx(struct HttpRequest* req) {
free(req->method);
free(req->url);
free(req->version);
if(req->reqHeaders != NULL) {
for(int i=0;i<req->reqHeadersNum;++i) {
free(req->reqHeaders[i].key);
free(req->reqHeaders[i].value);
}
free(req->reqHeaders);
}
httpRequestReset(req);
}
(四)销毁
// 销毁
void httpRequestDestroy(struct HttpRequest* req);
void httpRequestDestroy(struct HttpRequest* req) {
if(req != NULL) {
httpRequestResetEx(req);
free(req);
}
}
(五)学习笔记
一、关于指针与内存
- 在给指针赋值之前,需要先分配一块有效的内存
- 当浏览器客户端与服务器建立连接并进行多次通信时,需要多次向HttpRequest结构体中写入数据
- 如果需要重置HttpRequest结构体,只需重置指针指向的内存中的数据,而不需要销毁整个结构体的内存地址
- 当重置指针时,如果之前没有释放对应的内存,会导致内存泄漏
二、关于释放内存
- 在释放内存时,应先释放结构体成员中的指针所指向的内存
- 对于指向请求行数据的url、method和version,可以直接调用HTTP请求重置函数进行释放
- 对于结构体中的reqHeaders指针指向的内存,需要先判断指针是否为空,再释放对应的内存
三、注意事项
- 在使用指针之前,确保为其分配了有效的内存
- 在重置或释放内存后,确保指针指向正确的位置或设置为空
- 避免内存泄漏,确保在适当的时候释放已分配的内存
文章来源:https://blog.csdn.net/weixin_41987016/article/details/135460755
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!