zoukankan      html  css  js  c++  java
  • libevent的使用 32位 64位

      前段时间一个项目需要用到高并发的服务,想着自己应该可以写一个,windwos 上使用完成端口实现,写完之后,测试感觉没什么问题,可是一上线各种各样的问题,初步怀疑是底层网路库的问题,于是决定更换网络库,使用libevent 

      1,下载最新稳定版libevent

       http://libevent.org/ 目前最新稳定版本应该是libevent-2.1.8-stable.tar.gz 下载解压目录

      

      2,编译lib库

      使用VS命令提示工具编译:

      32位库的编译方法  

      cd  F:libeventlibevent-2.1.8-stable

      nmake /f Makefile.nmake

      会在根目录下生成三个文件libevent_core.lib,ibevent_extras.lib,libevent.lib 

      64位库的编译方法

      首先修改Makefile.nmake 在LIBFLAGS=/nologo 后面加上 /MACHINE:X64  

      cd  F:libeventlibevent-2.1.8-stable

      nmake /f Makefile.nmake

      顺利的话,根目录下同样会生成一个64位的库文件,  

      3,使用lib库

      新建一个lib文件夹,将上面编译好的lib文件放进去

      新建一个Include目录,将F:libeventlibevent-2.1.8-stableinclude下的文件和文件夹copy到该目录下,F:libeventlibevent-2.1.8-stableWIN32-Code下的文件copy到该目录下,2个event2目录下的文件可合并一起。

      然后,在项目工程中引用该include 和lib

    #ifndef WIN32
    #include <netinet/in.h>
    # ifdef _XOPEN_SOURCE_EXTENDED
    #  include <arpa/inet.h>
    # endif
    #include <sys/socket.h>
    #endif
    
    #include "event2/bufferevent.h"
    #include "event2/buffer.h"
    #include "event2/listener.h"
    #include "event2/util.h"
    #include "event2/event.h"
    
    #include <WinSock2.h>
    
    string IP = "127.0.0.1";
    int PORT = 9500;
    char * pMessage = "hello client";
    
    
    struct bevdata
    {
        string ip;
        int port;
    };
    static void conn_readcb(struct bufferevent *bev, void *ctx)
    {
        bevdata *pbev_data = (bevdata*)ctx;
        struct evbuffer* input = bufferevent_get_input(bev); 
        size_t len = evbuffer_get_length(input);
        printf("point = %x,len = %d",bev,len);
        struct evbuffer* output = bufferevent_get_output(bev);
        char msg[4096] = {0};
        len = bufferevent_read(bev, msg, sizeof(msg) - 1);
    
        printf("server recv data : %s:%d %s
    ",pbev_data->ip.c_str(),pbev_data->port,msg);
        char senddata[20];
        strcpy(senddata,"i recv your data");
        bufferevent_write(bev,senddata,strlen(senddata));
    }
    static void conn_writecb(struct bufferevent *bev, void *ctx)
    {
    
    
    }
    static void conn_eventcb(struct bufferevent *bev, short what, void *ctx)
    {
        if (what & BEV_EVENT_EOF) {
            printf("connection closed
    ");
        }
        else if (what & BEV_EVENT_ERROR) {
            printf("some other error
    ");
        }
    
        bufferevent_free(bev);
    
    }
    static void signal_cb(evutil_socket_t sig, short events, void *user_data)
    {
        struct event_base *base = (struct event_base *)user_data;
        struct timeval delay = { 2, 0 };
    
        printf("Caught an interrupt signal; exiting cleanly in two seconds.
    ");
    
        event_base_loopexit(base, &delay);
    }
    static void listener_cb(struct evconnlistener *listener, evutil_socket_t fd,
    struct sockaddr *sa, int socklen, void *user_data)
    {
        struct event_base * base = (struct event_base *)user_data;
        struct bufferevent * bev;
    
        bev = bufferevent_socket_new(base,fd,BEV_OPT_CLOSE_ON_FREE);
        if(!bev)
        {
            printf("error constructing bufferevent
    ");
            event_base_loopbreak(base);
            return ;
        }
        char temp[1024] = {0};
        // 将sockaddr强制转换为 sockaddr_in
        sockaddr_in sin;
        memcpy(&sin, sa, sizeof(sin));
        // 取得ip和端口号
        sprintf(temp, inet_ntoa(sin.sin_addr));
        bevdata *bev_data = new bevdata;
        bev_data->ip = temp;
        bev_data->port = sin.sin_port;
        printf("address = %s,port = %d,%x
    ",temp,sin.sin_port,bev);
        bufferevent_setcb(bev,conn_readcb,conn_writecb,conn_eventcb,bev_data);
        bufferevent_enable(bev, EV_WRITE);
        bufferevent_enable(bev, EV_READ);
    
        bufferevent_write(bev,pMessage,strlen(pMessage));
    }
    int _tmain(int argc, _TCHAR* argv[])
    {
    
        /*CCompleteIOWrapper complete ;
        complete.initComplete("127.0.0.1",9500);
        complete.startComplete();
    
        getchar();
        */
        struct event_base * base;
        struct evconnlistener * listener;
        struct event * signal_event;
        struct sockaddr_in sin;
    #ifdef WIN32
        WSADATA wsa_data;
        WSAStartup(0x0201,&wsa_data);
    #endif
    
        base = event_base_new();
        if(!base)
        {
            printf("cannot initailize libevent
    ");
            return 1;
        }
        memset(&sin,0,sizeof(sin));
        sin.sin_family = AF_INET;
        sin.sin_port = htons(PORT);
        sin.sin_addr.S_un.S_addr = inet_addr(IP.c_str());
    
        listener = evconnlistener_new_bind(base,listener_cb,(void*)base,
            LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE,-1,
            (struct sockaddr*)&sin,
            sizeof(sin));
        if(!listener)
        {
            printf("can not create a listener
    ");
            return 0;
        }
        signal_event = evsignal_new(base,SIGINT,signal_cb,(void*)base);
        if(!signal_event)
        {
            printf("can not create a signal event
    ");
            return 0;
        }
        printf("sertver starting...
    ");
        event_base_dispatch(base);
    
        evconnlistener_free(listener);
        event_free(signal_event);
        event_base_free(base);
        printf("done
    ");
        
        return 0;
    }

      5,编译好的库文件,奉献给大家 https://files.cnblogs.com/files/techdreaming/lib.zip

  • 相关阅读:
    站立会议05
    站立会议04
    站立会议03
    站立会议02
    kettle下载、配置及入门使用-数据库表的复制
    eclipse遇到启动报an error has occurred see the log file错 错误 修改了workplace工作空间
    云时代架构之中国民生银行天眼日志平台架构演进的平凡之路
    云时代架构之微店大数据开发平台架构演进
    云时代架构之微博深度学习平台架构和实践
    云时代架构之蘑菇街交易平台数据库架构演进历程
  • 原文地址:https://www.cnblogs.com/techdreaming/p/8322012.html
Copyright © 2011-2022 走看看