背景

新的c++11标准出后,c++语法得到了非常多的扩展,比起以往不论什么时候都要灵活和高效,提高了程序编码的效率,为软件开发者节省了不少的时间。

之前我也写过基于ACE的网络server框架,但ACE毕竟有些臃肿。内部对象关系错综复杂,easy给人造成仅仅见树木不见森林的错觉。 所以打算用c++11开发一个较为简洁,高效,支持高并发的网络库。

开源

        基础的结构已经开发完毕,代码也开源在github上。网址是 https://github.com/lichuan/fly 欢迎各位提出建议。

结构

fly网络库主要分为base模块,task模块,net模块。base主要是一些最基础的功能集合。包含日志。id分配器,随机数,队列等。task主要封装了任务抽象以及任务调度运行等功能;net主要是实现网络层面的封装。为上层使用者提供简单易用的网络接口,这也是fly库的核心模块。实现了解析协议的Parser封装,负责监听网络的Acceptor,负责网络连接io功能的Poller封装体,在Parser、Acceptor、和Poller的基础上还进一步封装了作为server来使用的Server类和作为client来使用的Client类,这两个类是fly库的核心类,上层的应用能够直接使用Server对象和Client对象来建立网络server。作为网络连接概念的Connection对象则是通过std::shared_ptr来管理它的生命周期的,shared_ptr内置共享对象的功能大大地简化了网络连接生命期的管理。

协议

fly库的网络协议基于全世界最通用的json格式。而它的解析则依赖于rapidjson第三方库来完毕。

协议组成例如以下:

|长度字段|{协议类型:类型值,协议命令:命令值,其它json字段}|

协议类型和协议命令组成了二级消息字,就能够组合出各种约定的协议了。

应用

fly库的test文件夹提供了一个简单的例程。当中test_server.cpp代码例如以下:

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* _______ _ *
* ( ____ \ ( \ |\ /| *
* | ( \/ | ( ( \ / ) *
* | (__ | | \ (_) / *
* | __) | | \ / *
* | ( | | ) ( *
* | ) | (____/\ | | *
* |/ (_______/ \_/ *
* *
* *
* fly is an awesome c++11 network library. *
* *
* @author: lichuan *
* @qq: 308831759 *
* @email: 308831759@qq.com *
* @github: https://github.com/lichuan/fly *
* @date: 2015-06-10 13:34:21 *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include <unistd.h>
#include <unordered_map>
#include "fly/init.hpp"
#include "fly/net/server.hpp"
#include "fly/base/logger.hpp" using namespace std::placeholders; class Test_Server : public fly::base::Singleton<Test_Server>
{
public:
bool allow(std::shared_ptr<fly::net::Connection> connection)
{
return true;
} void init(std::shared_ptr<fly::net::Connection> connection)
{
std::lock_guard<std::mutex> guard(m_mutex);
m_connections[connection->id()] = connection;
LOG_INFO("connection count: %u", m_connections.size());
} void dispatch(std::unique_ptr<fly::net::Message> message)
{
std::shared_ptr<fly::net::Connection> connection = message->get_connection();
const fly::net::Addr &addr = connection->peer_addr();
LOG_INFO("recv message from %s:%d raw_data: %s", addr.m_host.c_str(), addr.m_port, message->raw_data().c_str());
} void close(std::shared_ptr<fly::net::Connection> connection)
{
LOG_INFO("close connection from %s:%d", connection->peer_addr().m_host.c_str(), connection->peer_addr().m_port);
std::lock_guard<std::mutex> guard(m_mutex);
m_connections.erase(connection->id());
LOG_INFO("connection count: %u", m_connections.size());
} void be_closed(std::shared_ptr<fly::net::Connection> connection)
{
LOG_INFO("connection from %s:%d be closed", connection->peer_addr().m_host.c_str(), connection->peer_addr().m_port);
std::lock_guard<std::mutex> guard(m_mutex);
m_connections.erase(connection->id());
LOG_INFO("connection count: %u", m_connections.size());
} void main()
{
//init library
fly::init(); //init logger
fly::base::Logger::instance()->init(fly::base::DEBUG, "server", "./log/"); //test tcp server
std::unique_ptr<fly::net::Server> server(new fly::net::Server(fly::net::Addr("127.0.0.1", 8899),
std::bind(&Test_Server::allow, this, _1),
std::bind(&Test_Server::init, this, _1),
std::bind(&Test_Server::dispatch, this, _1),
std::bind(&Test_Server::close, this, _1),
std::bind(&Test_Server::be_closed, this, _1))); if(server->start())
{
LOG_INFO("start server ok!");
server->wait();
}
else
{
LOG_ERROR("start server failed");
}
} private:
std::unordered_map<uint64, std::shared_ptr<fly::net::Connection>> m_connections;
std::mutex m_mutex;
}; int main()
{
Test_Server::instance()->main();
}

Server对象构造时会要求传入监听地址和回调函数,当Server对象start启动时,fly库底层就会建立对应的Poller、Parser、Acceptor对象,假设想实现多线程Poller和Parser,则需传入并发线程数量就可以,回调函数说明例如以下:

allow_cb:当有新的连接到达时调用。来推断是否同意该连接的注冊。

init_cb:当把连接对象注冊到某一个Poller和Parser后调用,进行初始化处理。

dispatch_cb:当有消息到达时会调用,进行消息派发。

close_cb:主动关闭连接对象时调用。

be_closed_cb:检測到对端关闭连接对象时调用。

test_client.cpp主要使用Client对象来连接到某一个server,相同Client构造时也须要传入回调函数,其作用与Server构造时传入的回调一样。

基于c++11新标准开发一个支持多线程高并发的网络库的更多相关文章

  1. python 开发一个支持多用户在线的FTP

    ### 作者介绍:* author:lzl### 博客地址:* http://www.cnblogs.com/lianzhilei/p/5813986.html### 功能实现 作业:开发一个支持多用 ...

  2. Python3学习之路~8.6 开发一个支持多用户在线的FTP程序-代码实现

    作业: 开发一个支持多用户在线的FTP程序 要求: 用户加密认证 允许同时多用户登录 每个用户有自己的家目录 ,且只能访问自己的家目录 对用户进行磁盘配额,每个用户的可用空间不同 允许用户在ftp s ...

  3. C++11新标准学习

    <深入理解C++11:C++11新特性解析与应用> <华章科技:深入理解C++11:C++11新特性解析与应用>一共8章:第1章从设计思维和应用范畴两个维度对C++11新标准中 ...

  4. C++11新标准:nullptr关键字

    一.nullptr的意义 1.NULL在C中的定义 #define NULL (void*)0 2.NULL在C++中的定义 #ifndef NULL #ifdef __cplusplus #defi ...

  5. C++11新标准:decltype关键字

    一.decltype意义 有时我们希望从表达式的类型推断出要定义的变量类型,但是不想用该表达式的值初始化变量(如果要初始化就用auto了).为了满足这一需求,C++11新标准引入了decltype类型 ...

  6. C++11新标准:auto关键字

    一.auto意义 编程时常常需要把表达式的值赋给变量,这就要求在声明变量的时候清楚地知道表达式的类型,然后要做到这一点并非那么容易.为了解决这个问题,C++11新标准引入了auto类型说明符,用它就能 ...

  7. [开源] gnet: 一个轻量级且高性能的 Golang 网络库

    Github 主页 https://github.com/panjf2000/gnet 欢迎大家围观~~,目前还在持续更新,感兴趣的话可以 star 一下暗中观察哦. 简介 gnet 是一个基于 Ev ...

  8. c++11新标准for循环和lambda表达式

    :first-child { margin-top: 0px; } .markdown-preview:not([data-use-github-style]) h1, .markdown-previ ...

  9. 30分钟用Restful ABAP Programming模型开发一个支持增删改查的Fiori应用

    2016年时,Jerry曾经写过一系列关于SAP Fiori Smart Template(现在更名为Fiori Elements了)的博客,介绍了所谓的MDD开发方法论 - Metadata Dri ...

随机推荐

  1. 7/31 CSU-ACM2018暑期训练7-贪心

    比赛链接 A-CSU - 1588 现在有n堆果子,第i堆有ai个果子.现在要把这些果子合并成一堆,每次合并的代价是两堆果子的总果子数.求合并所有果子的最小代价. Input 第一行包含一个整数T(T ...

  2. Codeforces Round #423 A Restaurant Tables(模拟)

    A. Restaurant Tables time limit per test 1 second memory limit per test 256 megabytes input standard ...

  3. 并发系列5-大白话聊聊Java并发面试问题之微服务注册中心的读写锁优化【石杉的架构笔记】

  4. 【JavaScript】JS将Java的Timestamp转为Date类型

    遇到一个小需求,由于要填充日期插件里的数据,前台要把java后台传来的Date类型的数据转成YYYY-MM-DD格式的时间数据.通过json传输,Java的Date类型的数据自动转成了时间戳,例如 “ ...

  5. 【POJ 2409】 Let it Bead(置换、burnside引理)

    Let it Bead "Let it Bead" company is located upstairs at 700 Cannery Row in Monterey, CA. ...

  6. android viewpager fragment 优化 切换界面 延时加载

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha 使用 碎片的 设置用户可见暗示visible hint  这个方法来做到. hint 是 ...

  7. JZYZOJ1518 [haoi2011]b 莫比乌斯反演 分块 容斥

    http://172.20.6.3/Problem_Show.asp?id=1518最开始只想到了n^2的写法,肯定要超时的,所以要对求gcd的过程进行优化.首先是前缀和容斥,很好理解.第二个优化大致 ...

  8. 【状压dp】互不侵犯KING

    互不侵犯KING Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3866  Solved: 2264[Submit][Status][Discuss] ...

  9. Problem A: 零起点学算法80——逆序输出(数组练习)

    #include<stdio.h> int main() { ]; scanf("%d",&n); ;i<=n;i++){ scanf("%d& ...

  10. 93.数字三角形W(深搜)

    2189 数字三角形W  时间限制: 1 s  空间限制: 32000 KB  题目等级 : 黄金 Gold 题解 查看运行结果 题目描述 Description 数字三角形 要求走到最后mod 10 ...