简介
项目介绍:实现了一个基于协程的服务器框架,支持多线程、多协程协同调度;支持以异步处理的方式提高服务器性能;封装了网络相关的模块,包括socket、http、servlet等,支持快速搭建HTTP服务器或WebSokcet服务器。
详细内容:日志模块,使用宏实现流式输出,支持同步日志与异步日志、自定义日志格式、日志级别、多日志分离等功能。线程模块,封装pthread相关方法,封装常用的锁包括(信号量,读写锁,自旋锁等)。IO协程调度模块,基于ucontext_t实现非对称协程模型,以线程池的方式实现多线程,多协程协同调度,同时依赖epoll实现了事件监听机制。定时器模块,使用最小堆管理定时器,配合IO协程调度模块可以完成基于协程的定时任务调度。hook模块,将同步的系统调用封装成异步操作(accept, recv, send等),配合IO协程调度能够极大的提升服务器性能。Http模块,封装了sokcet常用方法,支持http协议解析,客户端实现连接池发送请求,服务器端实现servlet模式处理客户端请求,支持单Reator多线程,多Reator多线程模式的服务器。
Address模块
1. 主要功能
- 对Linux下ipv4和ipv6地址的封装
- 提供网络地址相关的类,支持与网络地址相关的操作,包括域名解析,网卡地址查询等
2. 功能演示
- 根据域名获取一个IP地址
Address::ptr addr = Address::LookupAnyIPAddress("www.baidu.com:80");
- 根据"ipv4的字符串格式"获取一个IP地址
IPv4Address::ptr addr = IPv4Address::Create("192.168.2.13", 9999);
3. 模块介绍
3.1 Address
- 所有网络类的基类,是对sockaddr的封装。主要关注地址类型,sockaddr指针,地址长度等内容。同时,还支持地址解析和本地网卡地址查询功能。
class Address
{
public:
typedef std::shared_ptr<Address> ptr;
....
}
- 地址解析。实现域名解析
// 通过host地址返回对应条件的所有Address,结果保存到result
bool Address::Lookup(std::vector<Address::ptr>& result, const std::string& host,
int family, int type, int protocol) {
addrinfo hints, *results, *next;
hints.ai_flags = 0;
hints.ai_family = family;
hints.ai_socktype = type;
hints.ai_protocol = protocol;
hints.ai_addrlen = 0;
hints.ai_canonname = NULL;
hints.ai_addr = NULL;
hints.ai_next = NULL;
std::string node;
const char* service = NULL;
//检查 ipv6address serivce
//host:
if(!host.empty() && host[0] == '[') {
const char* endipv6 = (const char*)memchr(host.c_str() + 1, ']', host.size() - 1);
if(endipv6) {
//TODO check out of range
if(*(endipv6 + 1) == ':') {
service = endipv6 + 2;
}
node = host.substr(1, endipv6 - host.c_str() - 1);
}
}
//检查 node serivce
if(node.empty()) {
service = (const char*)memchr(host.c_str(), ':', host.size());
if(service) {
if(!memchr(service + 1, ':', host.c_str() + host.size() - service - 1)) {
node = host.substr(0, service - host.c_str());
++service;
}
}
}
if(node.empty()) {
node = host;
}
int error = getaddrinfo(node.c_str(), service, &hints, &results);
if(error) {
LOG_DEBUG(g_logger) << "Address::Lookup getaddress(" << host << ", "
<< family << ", " << type << ") err=" << error << " errstr="
<< gai_strerror(error);
return false;
}
next = results;
while(next) {
result.push_back(Create(next->ai_addr, (socklen_t)next->ai_addrlen));
next = next->ai_next;
}
freeaddrinfo(results);
return !result.empty();
}
- 获取网卡地址
// 返回本机所有网卡的<网卡名, 地址, 子网掩码位数>
static bool GetInterfaceAddresses(std::multimap<std::string
,std::pair<Address::ptr, uint32_t> >& result, int family = AF_INET);
3.2 IPAddress
- 表示网络地址类。继承自Address类,表示一个IP地址,同样是一个抽象类,因为IP地址包含IPv4地址和IPv6地址。IPAddress类提供了IP地址相关的端口和掩码、网段地址、网络地址操作,无论是IPv4还是IPv6都支持这些操作,但这些方法都是抽象方法,需要由继承类来实现。
class IPAddress : public Address
{
public:
typedef std::shared_ptr<IPAddress> ptr;
// 通过域名,IP,服务器名创建IPAddress
static IPAddress::ptr Create(const char* address, uint16_t port = 0);
// 获取该地址的广播地址
virtual IPAddress::ptr broadcastAddress(uint32_t prefix_len) = 0;
// 获取该地址的网段
virtual IPAddress::ptr networdAddress(uint32_t prefix_len) = 0;
// 获取子网掩码地址
virtual IPAddress::ptr subnetMask(uint32_t prefix_len) = 0;
// 返回端口号
virtual uint16_t getPort() const = 0;
// 设置端口号
virtual void setPort(uint16_t v) = 0;
};
3.3 IPv4Address
- 继承自IPAddress类,表示一个IPv4地址。它包含一个sockaddr_in类型的成员,并且提供具体的端口设置/获取,掩码、网段、网络地址设置/获取操作。用于给定一个“ip地址(192.168.2.13)”或二进制ip地址,返回一个封装好的IPv4Address对象
class IPv4Address : public IPAddress
{
public:
typedef std::shared_ptr<IPv4Address> ptr;
// sockaddr_in构造IPv4Address
IPv4Address(const sockaddr_in& address);
// 通过二进制地址构造IPv4Address
IPv4Address(uint32_t address = INADDR_ANY, uint16_t port = 0);
static IPv4Address::ptr Create(const char* ip, uint16_t port);
const sockaddr* getAddr() const override;
sockaddr* getAddr() override;
socklen_t getAddrLen() const override;
std::ostream& insert(std::ostream& os) const override;
IPAddress::ptr broadcastAddress(uint32_t prefix_len) override;
IPAddress::ptr networdAddress(uint32_t prefix_len) override;
IPAddress::ptr subnetMask(uint32_t prefix_len) override;
uint16_t getPort() const override;
void setPort(uint16_t v) override;
private:
sockaddr_in m_addr;
};
3.4 IPv6Address
- 继承自IPAddress类,表示一个IPv6地址。用于给定一个“ipv6地址”或二进制ipv6地址,返回一个封装好的IPv6Address对象
class IPv6Address : public IPAddress {
public:
typedef std::shared_ptr<IPv6Address> ptr;
// 通过IPv6地址字符串构造IPv6Address
static IPv6Address::ptr Create(const char* address, uint16_t port = 0);
IPv6Address();
// 通过sockaddr_in6构造IPv6Address
IPv6Address(const sockaddr_in6& address);
// 通过IPv6二进制地址构造IPv6Address
IPv6Address(const uint8_t address[16], uint16_t port = 0);
const sockaddr* getAddr() const override;
sockaddr* getAddr() override;
socklen_t getAddrLen() const override;
std::ostream& insert(std::ostream& os) const override;
IPAddress::ptr broadcastAddress(uint32_t prefix_len) override;
IPAddress::ptr networdAddress(uint32_t prefix_len) override;
IPAddress::ptr subnetMask(uint32_t prefix_len) override;
uint16_t getPort() const override;
void setPort(uint16_t v) override;
private:
sockaddr_in6 m_addr;
};