WebServer项目——HTTPconnection详解

HTTPconnection简介

这个类就是对一个HTTP连接的抽象,负责对一个HTTP请求的解析和回复,以及提供读写的接口。

这个读写接口的底层就是靠buffer缓冲区来实现的,这个缓冲区提供了读写的接口。但是,写借口照样用了分散写的方法实现。然后就是对从socket连接中读取的数据进行解析,以及对请求做出响应。这部分的实现主要依赖于HTTPrequest和HTTPresponse来完成。

HTTPconnection组成

其中的构造函数和析构函数略去不谈,缺省就可以。

所需变量和自定义的数据结构

对于一个HTTP连接而言,我们需要用变量fd_唯一地标记它,用isClose_表示它是否需要关闭这个连接,已备后续关闭连接的函数的判断。一个HTTP连接还需要读写数据,所以给每一个HTTP连接定义一个读缓冲区和一个写缓冲区。在解析请求和响应请求的时候,我们借助HTTPrequest和HTTPresponse完成,所以也需要各种定义一个这两种变量。

总结一下,如下所示:

1
2
3
4
5
6
7
8
int fd_;                  //HTTP连接对应的描述符
bool isClose_; //标记是否关闭连接

Buffer readBuffer_; //读缓冲区
Buffer writeBuffer_; //写缓冲区

HTTPrequest request_;
HTTPresponse response_;

还需要一些其他的变量。比如响应请求的时候需要当前目录的路径这个值的传入,我们在这里需要定义它;比如,如果我们需要统计HTTP连接的个数,也就是用户的个数,最准确的方法就是在HTTP连接初始化和关闭的时候更改数据,在上层初始化它。

1
2
static const char* srcDir;
static std::atomic<int>userCount;

初始化和关闭连接的接口

这两个函数顾名思义就是用来初始化连接和关闭连接的时候使用的:

1
2
void initHTTPConn(int socketFd,const sockaddr_in& addr);
void closeHTTPConn();

读写接口

这个也很容易理解,每个HTTP连接都需要读写数据,这两个就是定义的读写接口:

1
2
ssize_t readBuffer(int* saveErrno);
ssize_t writeBuffer(int* saveErrno);

获取HTTP连接信息的函数

这个类也需要提供一些暴露给外界的接口,用于获取当前HTTP连接的信息:

1
2
3
4
5
6
const char* getIP() const;//获取IP信息
int getPort() const;//获取IP信息
int getFd() const;//获取HTTP连接的描述符,也就是唯一标志
sockaddr_in getAddr() const;
int writeBytes();//获取已经写入的数据长度
bool isKeepAlive() const;//获取这个HTTP连接KeepAlive的状态

主流程

这个类的主要函数就是用于完成解析请求和响应请求的整体逻辑,这些都在主函数中实现:

1
bool handleHTTPConn();

HTTPconnection的实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
class HTTPconnection{
public:
HTTPconnection();
~HTTPconnection();

void initHTTPConn(int socketFd,const sockaddr_in& addr);

//每个连接中定义的对缓冲区的读写接口
ssize_t readBuffer(int* saveErrno);
ssize_t writeBuffer(int* saveErrno);

//关闭HTTP连接的接口
void closeHTTPConn();
//定义处理该HTTP连接的接口,主要分为request的解析和response的生成
bool handleHTTPConn();

//其他方法
const char* getIP() const;
int getPort() const;
int getFd() const;
sockaddr_in getAddr() const;

int writeBytes()
{
return iov_[1].iov_len+iov_[0].iov_len;
}

bool isKeepAlive() const
{
return request_.isKeepAlive();
}

static bool isET;
static const char* srcDir;
static std::atomic<int>userCount;

private:
int fd_; //HTTP连接对应的描述符
struct sockaddr_in addr_;
bool isClose_; //标记是否关闭连接

int iovCnt_;
struct iovec iov_[2];

Buffer readBuffer_; //读缓冲区
Buffer writeBuffer_; //写缓冲区

HTTPrequest request_;
HTTPresponse response_;

};