加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

windows下用libevent 开发一个echo服务

发布时间:2020-12-14 02:32:33 所属栏目:Windows 来源:网络整理
导读:#include stdio.h#include string.h#include errno.h#include iostreamusing namespace std;#include event2/event.h#include event2/bufferevent.hvoid accept_cb(int fd,short events,void* arg);void socket_read_cb(bufferevent* bev,void* arg);void ev
#include <stdio.h>
#include <string.h>
#include <errno.h>

#include <iostream>
using namespace std;

#include <event2/event.h>
#include <event2/bufferevent.h>

void accept_cb(int fd,short events,void* arg);
void socket_read_cb(bufferevent* bev,void* arg);
void event_cb(struct bufferevent *bev,short event,void *arg);
int tcp_server_init(int port,int listen_num);

int main(int argc,char** argv)
{
#ifdef WIN32
    WSADATA wsa_data;
    WSAStartup(0x0201,&wsa_data);
#endif

    int listener = tcp_server_init(9999,10);
    if( listener == -1 )
    {
        perror(" tcp_server_init error ");
        return -1;
    }

    struct event_base* base = event_base_new();

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

    event_base_dispatch(base);
    event_base_free(base);

#ifdef WIN32
    WSACleanup();
#endif

    return 0;
}



void accept_cb(int fd,void* arg)
{
    evutil_socket_t sockfd;

    struct sockaddr_in client;
    int len = sizeof(client);

    sockfd = ::accept(fd,(struct sockaddr*)&client,&len );
    evutil_make_socket_nonblocking(sockfd);

    cout << "accept a client " << sockfd << endl;

    struct event_base* base = (event_base*)arg;

    bufferevent* bev = bufferevent_socket_new(base,sockfd,BEV_OPT_CLOSE_ON_FREE);
    bufferevent_setcb(bev,socket_read_cb,NULL,event_cb,arg);

    bufferevent_enable(bev,EV_READ | EV_PERSIST);
}



void socket_read_cb(bufferevent* bev,void* arg)
{
    char msg[4096] = {0};

    size_t len = bufferevent_read(bev,msg,sizeof(msg));

    cout << "recv the client msg: " << msg << endl;
    // msg[len] = ‘r‘; 
    // msg[len+1] = ‘n‘; 

    char reply_msg[4096] = "I have recvieced the msg: ";

    strcat(reply_msg + strlen(reply_msg),msg);
    bufferevent_write(bev,reply_msg,strlen(reply_msg));
}



void event_cb(struct bufferevent *bev,void *arg)
{

    if (event & BEV_EVENT_EOF)
    {
        cout << "connection closed" << endl;
    }
    else if (event & BEV_EVENT_ERROR)
    {
        cout << "some other error" << endl;
    }

    //这将自动close套接字和free读写缓冲区
    bufferevent_free(bev);
}


typedef struct sockaddr SA;
int tcp_server_init(int port,int listen_num)
{
    evutil_socket_t listener;

    listener = ::socket(AF_INET,SOCK_STREAM,0);
    if( listener == -1 )
        return -1;

    //允许多次绑定同一个地址。要用在socket和bind之间
    evutil_make_listen_socket_reuseable(listener);

    do
    {
        struct sockaddr_in sin;
        sin.sin_family = AF_INET;
        sin.sin_addr.s_addr = 0;
        sin.sin_port = htons(port);
        if( ::bind(listener,(SA*)&sin,sizeof(sin)) < 0 )
            break;

        if( ::listen(listener,listen_num) < 0)
            break;

        //跨平台统一接口,将套接字设置为非阻塞状态
        evutil_make_socket_nonblocking(listener);
        return listener;
    } while (0);

    int errno_save;
    errno_save = errno;
    evutil_closesocket(listener);
    errno = errno_save;

    return -1;
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读