libevent库的使用

Posted walkinginthesun

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了libevent库的使用相关的知识,希望对你有一定的参考价值。

参考:

1. libevent

使用第三方库我一般都偏爱最新的版本,libevent也是如此,所以我以 libevent-2.1.8-stable.tar.gz为例,在官网上可以下载。

编译、使用

./configure
make

头文件在include文件夹下,编译生成的动态库在.libs文件夹下。
技术分享图片

使用时,需要包含头文件和连接libevent.so动态库。

2. 示例

2.1 TcpServer.h

#ifndef TCP_SERVER_H
#define TCP_SERVER_H

struct event_base;

class TcpServer
{
public:
    using callback = void(int, short, void*);
    //typedef void (callback)(int, short, void*);

public:
    TcpServer(const int port);
    ~TcpServer();

    int Initialize();

    int Start();

    void Process();

private:
    int m_fd;
    int m_port;
    event_base* m_base;
    callback *m_accept_callback;
};

#endif  // TCP_SERVER_H

2.2 TcpServer.cpp

#include "TcpServer.h"

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>

#include "event.h"


void accept_cb(int fd, short events, void* arg)
{
    struct sockaddr_in client;
    socklen_t len = sizeof(client);

    int sockfd = ::accept(fd, (struct sockaddr*)&client, &len );
    printf("accept a client %d
", sockfd);

    TcpServer *pServer = static_cast<TcpServer*>(arg);
    pServer->Process();

    close(sockfd);
}


TcpServer::TcpServer(const int port):
    m_fd(-1),
    m_port(port),
    m_base(nullptr),
    m_accept_callback(nullptr)
    {
        m_accept_callback = accept_cb;
    }

TcpServer::~TcpServer()
{

}

int TcpServer::Initialize()
{
    m_fd = ::socket(AF_INET, SOCK_STREAM, 0);
    if( m_fd == -1 )
        return -1;

    struct sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = 0;
    sin.sin_port = htons(m_port);

    if( ::bind(m_fd, (struct sockaddr *)&sin, sizeof(sin)) < 0 )
    {
        return -2;
    }

    if( ::listen(m_fd, 10) < 0)
    {
        return -3;
    }

    return 0;
}

int TcpServer::Start()
{
    m_base = event_base_new();
    if(nullptr == m_base)
    {
        return -4;
    }

    //添加监听客户端请求连接事件  
    struct event* ev_listen = event_new(m_base, m_fd, EV_READ | EV_PERSIST,
                                        m_accept_callback, this);
    event_add(ev_listen, NULL);

    event_base_dispatch(m_base);

    return 0;
}

void TcpServer::Process()
{
    printf("process...
");
}

2.3 server.cpp

#include "TcpServer.h"

#include <unistd.h>
#include <memory>
#include <iostream>
using namespace std;

int main()
{
    shared_ptr<TcpServer> spServer = make_shared<TcpServer>(999);
    spServer->Initialize();
    spServer->Start();

    // while(true)
    // {
    //  sleep(1);
    // }
    return 0;
}

2.4 CMakeLists.txt

cmake_minimum_required(VERSION 2.6)
project(demo)

# 设置编译器(gcc/g++)
set(CMAKE_CXX_COMPILER "g++")

#设置Debug/Release
set(CMAKE_BUILD_TYPE "Debug")

# 设置编译选项
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pthread -g -Wall")

# 设置可执行二进制文件的目录
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

# 设置存放编译出来的库文件的目录
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
# 并把该目录设置为链接目录
link_directories(${PROJECT_SOURCE_DIR}/lib)

# 设定头文件目录
include_directories(${PROJECT_SOURCE_DIR}/include)

# 增加子文件夹(src路径是通过子文件夹形式添加)
add_subdirectory(${PROJECT_SOURCE_DIR}/src)
# 编译静态链接库libhello.a
# add_library(hello hello.cpp)

add_executable(server server.cpp TcpServer.cpp)
target_link_libraries(server libevent.so)

2.5 测试

可以通过curl命令来查看是否可以连接服务器

curl http://ip:port

以上是关于libevent库的使用的主要内容,如果未能解决你的问题,请参考以下文章

libuv和libev 异步I/O库的比较

掌握 libevent 网络库的正确姿势c/c++ linux服务器开发

浅谈libevent的使用--事件和数据缓冲

libevent和基于libevent的网络编程

libevent和基于libevent的网络编程

libevent和基于libevent的网络编程