本部分主要接着上一节,完成 HTTP 的响应报文。
1、生成HTTP响应工作流程
- 我们使用 writev( ) 来执行写操作,所以在这里将相应数据放在 iovec 结构体中,等待发送。
- 对于报错:响应首行、响应头部和响应体都在写缓冲中(write_buf)
- 对于文件请求,获取文件成功:响应首行和响应头部在 write_buf 中,响应体在 m_file_adress (目标文件在内存中的映射)
2、可变参数列表
C 语⾔中的可变参数就是将函数实现成可变参数的形式,可以使函数接收⼀个到多个参数(不固定)。va_list、va_start、va_arg、va_end。
对可变参数列表的处理过程一般为:
1、用 va_list 定义一个可变参数列表
2、用 va_start 获取函数可变参数列表
3、用 va_arg 循环处理可变参数列表中的各个可变参数
4、用 va_end 结束对可变参数列表的处理
/***************************** 求3个数的平均值 **************************/
#include<iostream>
#include<stdarg.h> // 头文件
using namespace std;
double ave(int num,...) // 形参列表是这样婶儿的
{
/* va_list:
定义一个可变参数列表,elem 实际上就是一个char指针,(char*)elem
*/
va_list elem;
/* va_start:
功能:初始化可变参数列表,有num组可变参数
参数1:可变参数列表
参数2:输入num
返回值:用于保存函数参数列表中可变参数的首指针(即,可变参数列表)
*/
va_start(elem, num);
int sum = 0;
int count = num; // 表示有几个数,求平均值的
while(num--)
{
/* va_arg:
第1个参数:可变参数列表名
第2个参数:正要处理的可变参数的类型
返回值:当前可变参数的值
*/
int px = va_arg(elem, int);
sum += px;
}
/* va_end:
用于结束对可变参数的处理
*/
va_end(elem);
return sum / count * 1.0;
}
int main()
{
cout << ave(3, 1, 2, 3) << endl;
return 0;
}
3、用到的API
#include <stdarg.h>
int vsnprintf(char *str, size_t size, const char *format, va_list ap);
- 功能:将可变参数格式化输出到一个字符数组
- 参数:
- str:把生成的格式化的字符串存放在这里
- size:str可接受的最大字符数
- format:指定输出格式的字符串,它决定了你需要提供的可变参数的类型、个数和顺序
- ap:va_list变量
- 返回值:
- 成功:返回最终生成字符串的长度
- 失败:返回负值
4、writev( ) 函数
不写了,给个链接(writev函数)
5、写HTTP响应
write( ) 函数中 writev( ) 函数将 HTTP 响应数据发送给客户端的 sockfd
附录
(main.cpp( )、http_conn.h、http_conn.cpp、和 Resource)
- 写到这里,代码也能访问这个HTML文件了
- 由于都要往写缓冲区中写入数据,所以定义了一个函数 add_response( ) ,之后调用即可,这里使用了多参数列表
- 代码中的报错的响应报文包含的内容如下
- 代码中的文件请求,获取文件成功的响应报文包含的内容如下