libevent 笔记 -API (2) bufferevent 、读写水位及超时

bufferevent_free  内部是引用计数,他会尽快的关闭,不会立即关闭,判断没有引用了才会关。

如果用bufferevent_write发送后立马调用bufferevent_free可能会导致部分数据(没有引用?)没有发出去(不要过早关闭)。

 

void socket_eventcb(struct bufferevent *bev, short events, void *user_data){
  if (events & BEV_EVENT_EOF) {
     bufferevent_free(bev);
  } else if (events & BEV_EVENT_ERROR) {
     bufferevent_free(bev);
  } else if(events & BEV_EVENT_TIMEOUT)

    bufferevent_free(bev);  //超时事件,规定时间内无响应,关闭客户端连接

    //超时时 EV_READ 是disable的,可以通过bufferevent_enable(bev, EV_READ)再把它置为可读,但是一般长时间没有响应都当成连接断开,通过bufferevent_free 释放bev(结合 FREE_ON_CLOSE属性关闭socket连接)
}

void socket_readcb(struct bufferevent *bev, void *user_data){
    char buffer[512] = {0};
    while(1){
        struct evbuffer *input = bufferevent_get_input(bev); //获取读取的evbuffer
        int length = evbuffer_get_length(input); 
        if (length <=0){
             bufferevent_write(bev, "ok12345\n", sizeof("ok\n"));  //bufferevent 的发送数据方式
             return;
        }
        int getlen = sizeof(buffer) -1;
        if(length < getlen){
            getlen = length;
        }
        unsigned int len = evbuffer_remove(input, buffer, getlen);//真正的读取数据并从evbuffer中移除
        if(len != getlen){
           cerr<<"read data len error:"<<strerror(errno)<<endl;
           return;
        }
        cout<<buffer<<endl;
    }
}

 

void socket_listenercb(struct evconnlistener *listener,  evutil_socket_t fd, struct sockaddr *sa, int socklen, void *user_data){


    int32_t enable = 1;
    setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (const char*) &enable, sizeof(enable));
    setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (const char*) &enable, sizeof(enable));
    evutil_make_socket_nonblocking(fd);

    struct event_base *base = evconnlistener_get_base(listener);
    bufferevent *bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);
    if (NULL == bev){
         return;
    }
    bufferevent_enable(bev, EV_READ | EV_WRITE | EV_PERSIST);
    //当收到字节长度小于低水位值时,不触发回调。当高于高水位值时,分批回调处理
    bufferevent_setwatermark(bev, EV_READ, 5, 10); //默认高、低水位值是0,而0表示无限制

    //网上对EV_WRITE的理解不是很准确

    bufferevent_setwatermark(bev, EV_WRITE, 5, 30); //并没有测出发送长度不够低水位值时不触发回调,相反是每次最多只能发送4个字节,write的高水位并没有用

    timeval t1 = {5, 0} ;  //设置read的超时时间
    bufferevent_set_timeouts(bev, &t1/*read*/, NULL /*write*/);

    bufferevent_setcb(bev, socket_readcb, NULL, socket_eventcb, user_data);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

字正腔圆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值