Libevent应用(六)从bufferevent中取出evbuffer

6 从bufferevent中取出evbuffer

struct evbuffer* bufferevent_get_input(struct bufferevent *bufev); //取出输入缓冲区
struct evbuffer* bufferevent_get_output(struct bufferevent *bufev); //取出输出缓冲区

/*对evbuffer的操作*/

//读到的一行内容
char *evbuffer_readln(struct evbuffer*buffer, size_t *n_read_out,enum evbuffer_eol_style eol_style); 
enum evbuffer_eol_style {
    EVBUFFER_EOL_ANY,            // 任意数量的\r和\n
    EVBUFFER_EOL_CRLF,           // \r或者\r\n
    EVBUFFER_EOL_CRLF_STRICT,    // \r\n
    EVBUFFER_EOL_LF,             // \n
    EVBUFFER_EOL_NUL             // \0
};

//将数据添加到evbuffer的结尾
int evbuffer_add(struct evbuffer *buf,const void *data, size_t datlen);  

//从evbuffer读取数据到data
int evbuffer_remove(struct evbuffer*buf, void *data, size_t datlen); 

//丢掉len字节的数据
int evbuffer_drain (struct evbuffer *buf, size_t len);

//返回evbuffer中存储的字节长度
size_t evbuffer_get_length(const structevbuffer *buf);  

/*在buffer中搜索指定字符串
第一个参数是搜索在evbuffer中,
第二个参数what是要搜索的字符串。
第三个参数len为what的字符串长度,
第四个参数,如果start不为空,则会从start中所指定的位置开始搜索,为NULL则从头开始找。
返回值:如果找到struct evbuffer_ptr的成员pos返回对应的索引,没有找到则pos返回-1*/
struct evbuffer_ptr evbuffer_search (struct evbuffer *buffer,
                                     const char *what,
                                     size_t len,
                                     const struct evbuffer_ptr *start);
//第二个函数的不同是指定了一个搜索范围;
struct evbuffer_ptr evbuffer_search_range (struct evbuffer *buffer,
                                           const char *what,
                                           size_t len,
                                           const struct evbuffer_ptr *start,
                                           const struct evbuffer_ptr *end);

struct evbuffer_ptr {
    ev_ssize_t pos;  //位置
    struct {/* internal fields */} _internal;
};

服务器综合代码:

/*************************************************************************
# File Name: tcp_server.c
# Author: wenong
# mail: huangwenlong@520it.com
# Created Time: 2016年09月03日 星期六 21时51分08秒
 ************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <ctype.h>
#include <arpa/inet.h>
#include <signal.h>
#include <errno.h>
#include <sys/wait.h>
#include <event2/event.h>
#include <event2/bufferevent.h>
#include <event2/buffer.h>
#include <event2/listener.h>
#define SERVERPORT 8888
#define MAXBYTES 1024

static struct event_base * base;

void write_buf_cb(struct bufferevent* bev, void* cbarg)
{
    printf("%s\n", __FUNCTION__);
}

void read_buf_cb(struct bufferevent* bev, void* cbarg)
{
    int ret, i;
    char buf[MAXBYTES];
    struct evbuffer* input_evbuffer = bufferevent_get_input(bev);   

    struct evbuffer_ptr begin, end;
    while(1)
    {
        /*读取a开头,b结尾的数据包*/
        begin = evbuffer_search(input_evbuffer, "a", 1, NULL); 
        printf("find a index %ld\n", begin.pos);
        if(begin.pos >= 0)
        {
            evbuffer_drain(input_evbuffer, begin.pos);
            end = evbuffer_search(input_evbuffer, "b", 1, NULL);
            if(end.pos > 0)
            {
                ret = evbuffer_remove(input_evbuffer, buf, end.pos - begin.pos + 1);
                buf[ret] = '\0';
                printf("read_buf_cd length %d\n", ret);
                for(i = 0; i < ret; i++)
                    buf[i] = toupper(buf[i]);
                bufferevent_write(bev, buf, ret);
            }
            else
                break;
        }
        else
        {
            bufferevent_flush(bev, EV_READ, BEV_NORMAL);
            break;
        }

    }

}
void event_cb(struct bufferevent* bev, short event, void* cbarg)
{
    if(BEV_EVENT_READING & event)
        puts("BEV_EVENT_READING");

    if(BEV_EVENT_WRITING & event)
        puts("BEV_EVENT_WRITING");

    if(BEV_EVENT_ERROR & event)
        puts("BEV_EVENT_ERROR");

    if(BEV_EVENT_EOF & event)
    {
        puts("BEV_EVENT_EOF");
        bufferevent_free(bev);
    }
    if(BEV_EVENT_TIMEOUT & event)
    {
        puts("BEV_EVENT_TIMEOUT");
        bufferevent_free(bev);
    }
}


void  accept_cb(struct evconnlistener *listener,
        evutil_socket_t clientfd, struct sockaddr *addr
        , int len, void *arg)
{

    struct bufferevent* bev;
    struct event_base* base = (struct event_base*)arg;
    puts("Accept client connect");
    evutil_make_socket_nonblocking(clientfd); 
    bev = bufferevent_socket_new(base, clientfd, BEV_OPT_CLOSE_ON_FREE 
            | BEV_OPT_DEFER_CALLBACKS);
    bufferevent_setcb(bev, (bufferevent_data_cb)read_buf_cb
            , (bufferevent_data_cb)write_buf_cb, (bufferevent_event_cb)event_cb, NULL);

    struct timeval timeout_read;
    timeout_read.tv_sec = 60;
    timeout_read.tv_usec = 0;
    bufferevent_set_timeouts(bev, &timeout_read, NULL);  
    bufferevent_setwatermark(bev, EV_READ, 10, 0);

    bufferevent_enable(bev, EV_READ);
}

void main_loop(struct sockaddr_in * addr)
{

    struct evconnlistener *evcon;
    base = event_base_new();
    evcon = evconnlistener_new_bind(base, (evconnlistener_cb)accept_cb
            , (void*)base, LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE
            , 128, (struct sockaddr*)addr, sizeof(struct sockaddr_in));

    puts("server begin listenning...");


    event_base_dispatch(base);
    evconnlistener_free(evcon);
    event_base_free(base);

}


int main(int argc, char** argv)
{
    int serverfd;
    socklen_t serveraddrlen;
    struct sockaddr_in serveraddr;
    serveraddr.sin_family = AF_INET;    
    serveraddr.sin_port = htons(SERVERPORT);
    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
    serverfd = socket(AF_INET, SOCK_STREAM, 0);
    serveraddrlen = sizeof(serveraddr);
    main_loop( &serveraddr);

    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Linux安装libevent可以按照以下步骤进行操作: 1. 首先,通过libevent的官网(https://libevent.org/)下载libevent的版本。 2. 下载完成后,解压缩下载的文件。 3. 打开终端,进入解压后的libevent目录。 4. 在终端运行以下命令,开始编译和安装libevent: ``` ./configure make sudo make install ``` 这些命令将会配置、编译和安装libevent。 5. 安装完成后,可以通过运行以下命令检查libevent是否成功安装: ``` ldconfig -v | grep libevent ``` 如果输出结果包含libevent.so动态库文件的路径,表示安装成功。 以上步骤可以确保在Linux系统成功安装libevent。如果在编译过程出现找不到库文件的错误,可以尝试以下解决方法: 1. 检查是否已经在/usr/lib目录下找到了libevent.so动态库文件。如果没有找到,可以通过创建软连接的方式解决。在终端运行以下命令: ``` ln -s 库文件绝对路径 /usr/lib/libevent.so ``` 这将会创建一个软连接,将库文件链接到/usr/lib目录。 通过以上步骤,您应该能够成功在Linux安装libevent,并解决相关的错误。希望对您有帮助!<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [【Linux】Linux系统下libevent库的安装](https://blog.csdn.net/qq_43411563/article/details/107413703)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [Linux环境下,安装libevent库](https://blog.csdn.net/xyz_unknown/article/details/128130408)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [Linux下编译安装php libevent扩展实例](https://download.csdn.net/download/weixin_38692666/12807205)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值