• libevent简单应用4


    #include <event2/listener.h>
    #include <event2/bufferevent.h>
    #include <event2/buffer.h>
    
    #include <arpa/inet.h>
    
    #include <string.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <errno.h>
    
    /* 设置计数,只允许echo_write_cb调用一次 */
    static int count = 1;
    
    /*当有数据可读的时候,会调用这个函数 */
    static void echo_read_cb(struct bufferevent *bev, void *ctx)
    {
    	printf("Echo_read_cb is called
    ");
    	struct evbuffer *input = bufferevent_get_input(bev);
    	struct evbuffer *output = bufferevent_get_output(bev);
    	
    	size_t len = evbuffer_get_length(input);
    	printf("evbuffer input length is: %lu
    ", (unsigned long)len);
    
    	//evbuffer_add_buffer(output, input);
    
    	char buf[1024];
    	int n;
    	n = evbuffer_remove(input, buf, sizeof(buf));
    	printf("copy bytes == %d
    ", n);
    	printf("copy buf: %s
    ", buf);
    }
    
    static void echo_write_cb(struct bufferevent *bev, void *ctx)
    {
    	printf("echo_write_cb is called
    ");
    	char sendbuffer[] = "yes, i recv your message!
    ";	
    
    	struct evbuffer *output = bufferevent_get_output(bev);	
    	
    	if(count == 1)
    	{
    		int result = evbuffer_add(output, sendbuffer, strlen(sendbuffer));
    		printf("evbuffer_add result = %d
    ", result);	
    	}
    	
    	count++;
    	int len = evbuffer_get_length(output);
    	evbuffer_drain(output, len);	
    }
    
    
    /*当客户端结束的时候,肯定会调用这个函数  */
    static void echo_event_cb(struct bufferevent *bev, short events, void *ctx)
    {
    	printf("echo_event_cb is called
    ");
    	if(events & BEV_EVENT_ERROR)
    		perror("Error from bufferevent");
    	if(events & BEV_EVENT_EOF | BEV_EVENT_ERROR)
    	{
    		bufferevent_free(bev);
    		printf("bufferevent_free is called
    ");
    	}
    }	
    
    
    static void accept_conn_cb(struct evconnlistener *listener, evutil_socket_t fd, 
    	struct sockaddr*address, int socklen, void *ctx)
    {
    	printf("Accept_conn_cb is called
    ");
    	struct event_base *base = evconnlistener_get_base(listener);
    	struct bufferevent *bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);
    	
    	bufferevent_setcb(bev, echo_read_cb, echo_write_cb, echo_event_cb, NULL);
    	
    	bufferevent_enable(bev, EV_READ|EV_WRITE);	
    }
    
    static void accept_error_cb(struct evconnlistener *listener, void *ctx)
    {	
    	printf("Accept_error_cb is called
    ");
    	struct event_base *base = evconnlistener_get_base(listener);
    	int err = EVUTIL_SOCKET_ERROR();
    	fprintf(stderr, "Got an error");
    	
    	event_base_loopexit(base, NULL);
    	
    }
    
    int main(int argc, char **argv)
    {
    	struct event_base *base;
    	struct evconnlistener *listener;
    	struct sockaddr_in sin;
    	
    	int port = 9527;
    	
    	if(argc > 1)
    	{
    		port = atoi(argv[1]);
    	}
    	if(port <= 0 || port > 65535)
    	{
    		puts("Invalid port");
    		return 1;
    	}
    
    	base = event_base_new();
    	if(!base)
    	{
    		puts("could't open event_base");
    		return 1;
    	}
    
    	memset(&sin, 0, sizeof(sin));
    	sin.sin_family = AF_INET;
    	sin.sin_addr.s_addr = htonl(0);
    	sin.sin_port = htons(port);
    	
    	listener = evconnlistener_new_bind(base, accept_conn_cb, NULL,
    		LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE, -1,
    		(struct sockaddr*)&sin, sizeof(sin));
    	if(!listener)
    	{
    		perror("could't not create listener");
    		return 1;
    	}
    	
    	evconnlistener_set_error_cb(listener, accept_error_cb);
    	
    	event_base_dispatch(base);
    	return 0;
    }

    说明:

    利用evconnlistener_new_bind实现一个tcp服务器端,evconnlistener_new_bind源码本身调用了evconnlistener_new函数,源码已经封装了Bind和Listen函数。


  • 相关阅读:
    spring aop
    Linux进程管理命令
    逻辑卷管理-LVM(Logical Volume Manager)
    Linux磁盘与文件系统管理(二)
    Linux磁盘与文件系统管理(一)
    Linux后台运行和关闭、查看后台任务
    Linux用户管理及用户信息查询
    文件备份与压缩
    Liunx信息显示与文件搜索
    文本处理三剑客之 awk
  • 原文地址:https://www.cnblogs.com/chunlinge/p/3491330.html
Copyright © 2020-2023  润新知