ufnslab / KQEvent

一个非阻塞网络库

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

#KQEvent https://github.com/EmbolismSoil/KQEvent/archive/master.zip

KQEvent是一个LINUX下的Reactor网络库,使用C++11实现。意图展示一个基本的异步非阻塞网络库的实现,最终会在此基础上实现一个Http Server和一个RPC框架。 KQEvent的设计目标是:方便使用

编译

./build.sh

编译之后会看到build目录下面有samples文件夹,里面是一些示例。

###示例:

TCPServer示例

void TestServer(void){
    auto server = TCPServer::newInstance("127.0.0.1:12000");
    server->setConnectionNewHandler([](ConnectionPtr conn){
        std::cout << "new connection from "
                  << conn->getPeerAddr()->toString()
                  << " to " << conn->getHostAddr()->toString()
                  << std::endl;
    });

    server->setConnectionReadHandler([](ConnectionPtr conn, char *buf, size_t len){
        char msg[] =
                "HTTP/1.1 200 OK\n"
                        "Server: GitHub.com\n"
                        "Date: Mon, 19 Sep 2016 05:06:46 GMT\n"
                        "Content-Type: text/html; charset=utf-8\n"
                        "\n"
                        "<html>\n"
                        "<body>\n"
                        "\n"
                        "<h1>KQEvent</h1>"
                        "<a href=\"http://github.com/EmbolismSoil/KQEvent\">\n"
                        "View source</a>\n"
                        "\n"
                        "</body>\n"
                        "</html>";
        conn->sendMessage(msg, sizeof(msg));
        conn->softClose();
    });

    server->setConnectionCloseHandler([](ConnectionPtr conn){
        std::cout << " disconnect from "
                  << conn->getPeerAddr()->toString()
                  << " to " << conn->getHostAddr()->toString()
                  << std::endl;
    });

    server->run();
}

运行simpleServer,打开浏览器输入地址127.0.0.1:12000你会看到:

TCPServre Sendfile示例

你可以利用sendfile直接发送文件,以避免用户空间和内核空间之间的过多拷贝

    auto server = TCPServer::newInstance("127.0.0.1:12000");
    server->setConnectionNewHandler([](ConnectionPtr conn){
        std::cout << "new connection from "
                  << conn->getPeerAddr()->toString()
                  << " to " << conn->getHostAddr()->toString()
                  << std::endl;
    });

    server->setConnectionReadHandler([](ConnectionPtr conn, char *buf, size_t len){
        conn->sendFile("doc/simpleServer.cpp");
        conn->softClose();
    });

    server->setConnectionCloseHandler([](ConnectionPtr conn){
        std::cout << " disconnect from "
                  << conn->getPeerAddr()->toString()
                  << " to " << conn->getHostAddr()->toString()
                  << std::endl;
    });

    server->run();

用浏览器打开地址127.0.0.1:12000你可以看到:

TCPClient示例

void TestClient(void){
    std::string serverAddr("127.0.0.1:12000");
    auto client = TCPClient::newInstance(serverAddr);

    client->onConnected([](TCPClient::ConnectionPtr conn){
        std::cout << "connect from " << conn->getHostAddr()->toString()
                  << " to " << conn->getPeerAddr()->toString()
                  << "...OK" << std::endl;
    });

    client->onRead([&client](char *buf, size_t n){
        buf[n] = '\0';
        std::cout << buf << std::endl;
        char msg[] = "message from Client\n";
        client->sendMsg(msg, sizeof(msg));
    });

    client->onClose([](TCPClient::ConnectionPtr conn){
        std::cout << "disconnect from " << conn->getHostAddr()->toString()
                  << " to " << conn->getPeerAddr()->toString()
                  << "...OK" << std::endl;
        ::exit(0);
    });

    client->run();
}

打开终端使用nc -l -n 127.0.0.1 -p 12000监听端口, 运行TCPClient, 连接成功后随意输入字符串,你可以看到:

nc所在的终端随意输入字符串,比如输入test你会看到:

###将会实现的特性

  • 用户可以从内存池中分配内存,内存池跟踪内存的使用情况,跟踪内存生命周期,提供丰富的调试信息,必要时自动回收。降低用户内存管理的难度。
  • 实现性能统计,可以在调试模式自动导出统计数据的图表形式。
  • 基于无锁结构设计的高性能线程池
  • 向用户提供高效的零拷贝的工具集

###正在进行的工作

  • 对SIGPIPE信号的处理进行设计
  • Buffer的设计
  • Connection发送消息封装成消息包
  • 线程池

License

GPLv2

About

一个非阻塞网络库


Languages

Language:Makefile 45.8%Language:C++ 36.5%Language:CMake 12.2%Language:C 5.4%Language:Shell 0.1%