The anet libraries are server modules which support tcp/http with server and client mode, log, timer, pool module and so on.
The tcp client example:
#include <chrono>
#include "all.hpp" // tcp client header.
#include "log.h"
#include "default_interface.hpp"
// define sleep ms.
#define sleepMS(x) std::this_thread::sleep_for(std::chrono::milliseconds(x))
void main() {
anet::tcp::Client client(2);
client.setPacketParser(new anet::tcp::CBigCodec());
for (;;) {
auto session = new anet::tcp::CSession();
client.setSession(session);
while (client.syncConnect("10.24.11.20", 5566)) {
break;
}
session->sendMsg(1, "hello");
session->close();
sleepMS(10);
}
}
The tcp client for synchronous mode
#include "all.hpp" // tcp client header.
#include "log.h"
#include "default_interface.hpp"
void main() {
anet::tcp::Client client(2);
client.setPacketParser(new anet::tcp::CBigCodec());
// Synchronous session.
auto session = new anet::tcp::CSyncSession();
client.setSession(session);
if (!client.syncConnect("127.0.0.1", 5566)) {
return -1;
}
// send message asynchronously.
long long id = 0;
auto send = [session,&id]() {
std::string strIndex = std::to_string(id++);
auto msgId = 1;
auto &&msg = strIndex;
session->Send(msgId, msg);
};
// thread and its execution body.
std::thread th([session]() {
long long id = 0;
for (;;) {
// require message from server synchronously.
std::string strIndex = std::to_string(id++);
auto res = session->require(1, strIndex);
Ainfo("{}:{}",res.msgId, res.message.c_str());
// sleepMS(1);
}
});
th.detach();
// main thread to do it.
for (;;) {
send();
sleepMS(1);
}
}
The tcp server example:
// first declare CClientSession defined as followings:
#include <functional>
#include "share_ptr_session.hpp"
#include "log.h"
// get thread id.
inline unsigned int getThreadId() {
std::thread::id this_id = std::this_thread::get_id();
return *(unsigned int*)&this_id;
}
class CClientSession;
using SharePtrSession = anet::tcp::CSharePtrSession<CClientSession>;
class CClientSession {
public:
CClientSession() = default;
virtual ~CClientSession() = default;
public:
// on message callback.
void OnMessage(const char *msg, int len) {
const char *content = msg + gProto_head_size;
auto msgId = ntohs(*(uint16*)(content));
Adebug("msg id:{},msg:{},thread id:{}", msgId, content + sizeof(uint16), getThreadId());
m_pSession->Send(msg, len);
}
// on tcp connection connected.
void OnConnected() {
Adebug("{} {}, thread id:{}", m_pSession->getRemoteIP(), "connected in", getThreadId());
}
// on tcp connection terminate.
void OnTerminate() {
Adebug("{} {}, thread id:{}", m_pSession->getRemoteIP(), "disconnected in", getThreadId());
}
void SetSession(SharePtrSession *pSession) {
m_pSession = pSession;
}
private:
// session pointer.
SharePtrSession *m_pSession;
};
// end of the client session declaration.
// main function as following:
#include <chrono>
#include "all.hpp" // tcp server header.
#include "log.h"
#include "default_interface.hpp"
// define sleep ms.
#define sleepMS(x) std::this_thread::sleep_for(std::chrono::milliseconds(x))
void main() {
// tcp server.
// anet::tcp::CEventLoop loop(2);
// anet::tcp::CServer server(loop);
anet::tcp::Server server(3);
server.proxy().setPacketParser(new anet::tcp::CBigCodec());
// server.proxy().setSessionFactory(new anet::tcp::CSessionFactory());
using userSessionType = anet::tcp::CSharePtrSession<CClientSession>;
using userSessionFactoryType = anet::tcp::CSharePtrSessionFactory<userSessionType>;
auto sessionFactory = new userSessionFactoryType();
server.proxy().setSessionFactory(sessionFactory);
if (!server.proxy().start("0", 5566)) {
return -1;
}
// main thread run.
bool busy = false;
int runCount = 1000000;
for (;;) {
busy = false;
// tcp net run.
if (CMainService::instance().run(runCount)) {
busy = true;
}
// timer run.
STimeWheelSpace::CTimeWheel::instance().run();
if (!busy) {
sleepMS(1);
}
}
}
#include <chrono>
#include "all.hpp" // http client header.
#include "log.h"
// define sleepMS.
#define sleepMS(x) std::this_thread::sleep_for(std::chrono::milliseconds(x))
void main() {
// http client test.
// http synchronous session factory.
auto sessionFactory = new anet::http::httSyncSessionFactory;
int gSize = 10;
for (int i = 0; i < gSize; i++) {
auto thrd = std::make_unique<std::thread>([sessionFactory]() {
anet::http::CHttpSyncClient client(sessionFactory);
for (;;) {
// get requirement
auto getRet = client.get("10.24.11.20:8335", "/anet", "");
AInfo("status:%d,content:%s", getRet.first, getRet.second.c_str());
// post requirement
auto postRet = client.post("10.24.11.20:8335", "/anet", "");
AInfo("status:%d,content:%s", postRet.first, postRet.second.c_str());
// sleepMS(1);
}
});
thrd->detach();
}
for (;;) {
sleepMS(1000);
}
// just for the code's rightness.
delete sessionFactory;
The http server example:
#include <chrono>
#include "all.hpp" // http server header.
#include "log.h"
// define sleepMS.
#define sleepMS(x) std::this_thread::sleep_for(std::chrono::milliseconds(x))
void main() {
anet::http::CHttpServer server(2);
// == define all kinds of post interfaces.
server.post("/anet", [](const anet::http::HttpRes& res) ->anet::http::httpResPair {
return { anet::http::httpStatus::OK, std::move(std::string("hello,post anet")) };
});
server.get("/anet", [](const anet::http::HttpRes& res) ->anet::http::httpResPair {
return { anet::http::httpStatus::OK, std::move(std::string("hello,get anet")) };
});
server.start("0", 8335);
// wait for exit
for (;;) {
sleepMS(1);
}
}
#include "log.h" // log header.
#include <chrono>
// define sleepMS.
#define sleepMS(x) std::this_thread::sleep_for(std::chrono::milliseconds(x))
void main() {
// init log module
anet::log::initLog("./log", "test-net", anet::log::eLogLevel::debug, 1000);
// set log level.
if (argc >= 2) {
anet::log::setLogLevel(anet::log::eLogLevel(atoi(argv[1])));
} else {
anet::log::setLogLevel(anet::log::eLogLevel::debug);
}
// log out synchronously with {} flag.
Adebug("{}", "=== start ===");
// log out synchronously with {} flag.
debug("{}", "=== start ===");
// log out synchronously with traditional(%d,%s) flag.
Debug("%s", "=== end ===")
// log out synchronously with traditional(%d,%s) flag.
ADebug("%s", "=== end ===")
for (;;) {
sleepMS(1);
}
}
The timer example:
#include <chrono>
#include <stdlib.h>
#include "time_wheel.h" // timer header.
// define sleepMS.
#define sleepMS(x) std::this_thread::sleep_for(std::chrono::microseconds(x))
void main() {
// create timer register.
STimeWheelSpace::CTimerRegister timer;
// add 0 once timer(10s).
timer.add_once_timer([](void*) {
printf("0 timer out");
}, 0, 10 * 1000);
// add 1 repeated timer(1s).
timer.add_repeated_timer([&timer](void*) {
printf("1 timer out");
// kill the 1 timer.
timer.kill_timer(1);
}, 1, 1000);
// run variadic template function after 1s.
m_register.add_var_once_timer(0, 1000, [](std::string a, int b, int c) {
Adebug("a:{},b:{},c:{}", a, b, c);
}, "1", 2, 3);
// run the timer to execute the events.
for (;;) {
STimeWheelSpace::CTimeWheel::instance().run();
sleepMS(10);
}
}
Install cmake, and compile this module(CMakeLists.txt) to STATIC or SHARED library.
All the modules run well in vc-studio2017 and Linux g++(7.5.0)version. And the compiler must support c++17 for std::apply and std::any.
The tcp server for the upper single thread can reach 40W QPS at 8CPU and 16G memory of Linux. And the QPS can reach 80W if the tcp server using multiple thread for the upper logic. (服务器上层使用单线程模式,8核16G的i7Linux上,50W+的QPS;如果上层是多线程模式,在上述环境能达到80W+的QPS)。
If you want to compile the anet module in windows, you can open the anet with vscode, and it will produce build fold including anet.sln. then you can open it with vc-studio2017. (如果你想用windows的vc-studio2017打开这个库,你只需要用vscode打开这个库,然后vscode会自动帮你生成build目录,里面包含anet.sln)。
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。
1. 开源生态
2. 协作、人、软件
3. 评估模型