evpp是奇虎360内部使用的开源多线程网络库,集tcp/udp/http多种协议的服务器和客户端支持。github代码路径是:https://github.com/Qihoo360/evpp,可以不依赖boost库,使用现代c++14语言(evpp/invoke_timer.cc的lambda表达式使用到了c++14的特性)进行编码。本项目高度参考了muduo网络库,而底层使用现成的libevent库作为事件驱动库,典型的一个reactor网络编程模式的例子,本文就是通过分析evpp源码来达到学习c++网络编程的效果。
muduo代码我也拜读过,muduo有个特点,它完全是为linux而写的(譬如里面用到了eventfd,timerfd以及epoll等,都是linux系统特有的,而且还跟linux版本有关,系统版本太低也不支持,譬如eventfd),而evpp做了一定的平台兼容性,能一定程度做到支持windows平台,得益于libevent库。另外,木铎有个base库,是重复造轮子了,其他还好,也是一个不可多得的多线程网络服务器编程demo,值得参考,而evpp没有像muduo那样重新实现一套基础库(如线程库、互斥锁、条件变量等),而是利用了c++14自带的std::thread、std::mutex等,相对通用很多,而且学习这些类库使用在其他项目也能用得着,毕竟是c++的标准类库。
摘抄了github上的说明,大家可以点进去前文给出的github路径阅读Readme:
我们先给出基础的TCP服务器和客户端的例子,http的话我就不讲解了。
TCP服务器端例子:
#include <evpp/tcp_server.h>
#include <evpp/buffer.h>
#include <evpp/tcp_conn.h>
int main(int argc, char* argv[]) {
std::string addr = "0.0.0.0:9099";
int thread_num = 4;
evpp::EventLoop loop;
evpp::TCPServer server(&loop, addr, "TCPEchoServer", thread_num);
server.SetMessageCallback([](const evpp::TCPConnPtr& conn,
evpp::Buffer* msg) {
LOG_INFO << "SetMessageCallback string: " << msg->ToString() << LOG_LR;
conn->Send(msg);
});
server.SetConnectionCallback([](const evpp::TCPConnPtr& conn) {
if (conn->IsConnected()) {
LOG_INFO << "A new connection from " << conn->remote_addr() << LOG_LR;
} else {
LOG_INFO << "Lost the connection from " << conn->remote_addr() << LOG_LR;
}
});
server.Init();
server.Start();
loop.Run();
return 0;
}
而TCP客户端例子:
#include <evpp/tcp_client.h>
#include <evpp/buffer.h>
#include <evpp/tcp_conn.h>
int main(int argc, char* argv[]) {
std::string addr = "127.0.0.1:9099";
if (argc == 2) {
addr = argv[1];
}
evpp::EventLoop loop;
evpp::TCPClient client(&loop, addr, "TCPPingPongClient");
client.SetMessageCallback([&loop, &client](const evpp::TCPConnPtr& conn,
evpp::Buffer* msg) {
LOG_TRACE << "Receive a message [" << msg->ToString() << "]" << LOG_LR;
client.Disconnect();
});
client.SetConnectionCallback([](const evpp::TCPConnPtr& conn) {
if (conn->IsConnected()) {
LOG_INFO << "Connected to " << conn->remote_addr() << LOG_LR;
conn->Send("hello");
} else {
conn->loop()->Stop();
}
});
client.Connect();
loop.Run();
return 0;
}
看得出来类的使用跟muduo如出一辙,也是抛弃c++的继承,积极使用"std::function+std::bind"两兄弟。作者也是致敬了一番muduo库。
来源:oschina
链接:https://my.oschina.net/u/4375750/blog/4335334