libevent使用socket实例

该博客介绍了如何使用libevent库创建一个跨平台的TCP服务器。通过evconnlistener_new_bind函数一次性完成bind和listen操作,设置socket为非阻塞和可复用,并使用event_base_dispatch进行事件轮询。当接收到客户端连接时,服务器会创建新的事件处理客户端的读取请求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用socket实例

使用宏把文件描述符封装了一层

#define evutil_socket_t int

evutil_socket_t listen_socket = socket(AF_INET, SOCK_STREAM, 0);

一次性将bind listen全部完成

evconnlistener *ev = evconnlister_new_bind(base
                                        list_cb,
                                        LEV_OPT_reuseable,
                                        10,                                      (socketaddr*)&serv_adr,
                     sizeof(serv_adr));

设置非阻塞和端口复用

evutil_make_socket_nonblocking(listen_socket);
evutil_make_listen_socket_reuseable(listen_socket);

event_base_dispatch开启事件轮询

evutil_closesocket(文件描述符)跨平台的函数,对应Windows的closesocket和Linux的close

evutil_inet_ntop也是跨平台封装的函数,因为在Linux和Windows下不在同一个头文件

 evutil_inet_ntop(AF_INET,&sin.sin_addr,ip,sizeof(ip)-1);

CMakeLists.txt

project(test)
cmake_minimum_required(VERSION 3.1)
include_directories(./)

aux_source_directory(. DIRSRCS)
add_executable(test ${DIRSRCS})
target_link_libraries(test pthread event event_pthreads)

master.hpp

#ifndef __MASTER__HPP__
#define __MASTER__HPP__
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <event2/event.h>

#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#define SPORT 5001
class Cwork
{
    public:
    Cwork()
    {
        memset(&m_sin,0,sizeof(m_sin));
    }
    ~Cwork()
    {
        event_base_free(m_base);
        event_free(m_ev);
    }
    public:
    void init();

    private:
    event_base *m_base;
    evutil_socket_t list_event_tcp;
    sockaddr_in m_sin;
    socklen_t len;
    event* m_ev;
};
using namespace std;
#endif

master.hpp

#include "master.hpp"
void client_cb(evutil_socket_t s,short w,void *arg);
void read_file(evutil_socket_t fd,short w,void *arg)
{
    cout<<"."<<endl;
    sockaddr_in sin;
    socklen_t size = sizeof(sin);
    evutil_socket_t client = accept(fd,(sockaddr*)&sin,&size);
    char ip[16]={0};
    evutil_inet_ntop(AF_INET,&sin.sin_addr,ip,sizeof(ip)-1);
    cout<<"clientg ip is "<<ip<<endl;
    event_base *base =(event_base*)arg;

    // 响应客户端的消息
    event *ev = event_new(base,client,EV_READ|EV_PERSIST,client_cb,event_self_cbarg());
    timeval t={10,0};
    event_add(ev,&t);
}
void client_cb(evutil_socket_t s,short w,void *arg)
{
    char buf[1024] = {0};
    int len = recv(s,buf,sizeof(buf)-1,0);
    if(len >0)
        cout<<buf<<endl;
    else
    {
        event *ev=(event*)arg;
        event_free(ev);
        evutil_closesocket(s);

    }
}
void Cwork::init()
{
    m_base = event_base_new(); // 创建上下文
    list_event_tcp = socket(AF_INET,SOCK_STREAM,0);
    if(list_event_tcp <= 0)
    {
        cout<<"socket error "<<endl;
    }

    evutil_make_socket_nonblocking(list_event_tcp);

    evutil_make_listen_socket_reuseable(list_event_tcp);

    m_sin.sin_family = AF_INET;
    m_sin.sin_port = htons(SPORT);
    int ret = ::bind(list_event_tcp,(sockaddr*)&m_sin,sizeof(m_sin));

    if(ret != 0)
    {
        cerr<<"bind error"<<endl;
    }
    listen(list_event_tcp,10);
    
    m_ev = event_new(m_base,list_event_tcp,EV_READ|EV_PERSIST,read_file,m_base);
    event_add(m_ev,0);
    event_base_dispatch(m_base);
}

main.cpp

#include "master.hpp"
void client_cb(evutil_socket_t s,short w,void *arg);
void read_file(evutil_socket_t fd,short w,void *arg)
{
    cout<<"."<<endl;
    sockaddr_in sin;
    socklen_t size = sizeof(sin);
    evutil_socket_t client = accept(fd,(sockaddr*)&sin,&size);
    char ip[16]={0};
    evutil_inet_ntop(AF_INET,&sin.sin_addr,ip,sizeof(ip)-1);
    cout<<"clientg ip is "<<ip<<endl;
    event_base *base =(event_base*)arg;

    // 响应客户端的消息
    event *ev = event_new(base,client,EV_READ|EV_PERSIST,client_cb,event_self_cbarg());
    timeval t={10,0};
    event_add(ev,&t);
}
void client_cb(evutil_socket_t s,short w,void *arg)
{
    char buf[1024] = {0};
    int len = recv(s,buf,sizeof(buf)-1,0);
    if(len >0)
        cout<<buf<<endl;
    else
    {
        event *ev=(event*)arg;
        event_free(ev);

    }
}
void Cwork::init()
{
    m_base = event_base_new(); // 创建上下文
    list_event_tcp = socket(AF_INET,SOCK_STREAM,0);
    if(list_event_tcp <= 0)
    {
        cout<<"socket error "<<endl;
    }

    evutil_make_socket_nonblocking(list_event_tcp);

    evutil_make_listen_socket_reuseable(list_event_tcp);

    m_sin.sin_family = AF_INET;
    m_sin.sin_port = htons(SPORT);
    int ret = ::bind(list_event_tcp,(sockaddr*)&m_sin,sizeof(m_sin));

    if(ret != 0)
    {
        cerr<<"bind error"<<endl;
    }
    listen(list_event_tcp,10);
    
    m_ev = event_new(m_base,list_event_tcp,EV_READ|EV_PERSIST,read_file,m_base);
    event_add(m_ev,0);
    event_base_dispatch(m_base);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值