libevent

libevent

UDP

在这里插入图片描述

UDP实现C/S模型
	recv()/send()  只能使用TCP通信,替代read\write;
自身就是一个并发处理,本来就是没有建立连接。
server: socket()---->bind()----listen()[可有可无]while(1){
			read()-----被替换----recvfrom();
			wtrite()---被替换----sendto()
		}
client:
		connfd=socket(AF_INET,SOCK_DGRAM,0)sendto(“服务器地址”,地址结构大小)recvfrom();
		close();

ssize_t recvfrom(int sockfd,void * buf,size_t len ,int flags,
                	struct sockaddr* src_addr,socklen_t * addrlen);
ssize_t sendto(int sockfd,void * buf,size_t len ,int flags,
              	const struct sockaddr* dst_addr,socklen_t* addrlen);
本地套接字:
IPC  
	pipe:应用性最强的
	fifo:可以没有血缘关系
	mmap:没有血缘且可以输入输出
    信号:开销最小的 
    本地套接字(domain):最稳定的
1.int socket(int domain,int type,int protocol)  
        domain---AF_UNIX,AF_LOCAL
        type-----SOCK_STREAM/SOCK_DGRAM
2. 地址结构:
        sockaddr_in  -----------------  sockaddr_un
 struct sockaddr_in srv_addr----------->struct sockaddr_un srv_addr;
 srv_addr.sin_family=AF_INET;---------->sev_addr.sun_family=AF_UNIX;
 srv_addr.sin_port=htons(port);-------->strcpy(srv_addr.sun_path,"srv.socket");
 srv_addr.sin_addr.s_addr=htonl(INADDR_ANY)----X
 bind(fd,(struct sockaddr*)&sev_addr,sizeof(sev_addr))--------
 ----->(len=2+strlen("srv.socket"))/bind(fd,(struct sockaddr*)&srv_addr),len);
-------len=offsetof(struct sockaddr_un,sun_path)++strlen("srv.socket");(查看一个成员变量在结构中的偏移位置)

3.bind()函数调用成功,会创建一个socket文件(伪文件)。因此为保证bind成功,通常我们在bind之前,可以使用unlink("sev,sock");
4.客服端不能依赖隐式绑定,并且在通讯建立中,创建且初始化2个地址结构(自己的和服务区的);
libevent库

优点:开源 、跨平台、精简。专注网络通信

特征:基于“事件” 异步 通信模型(函数的创建和调用不一样)

与编码包安装:
​	./configure  检查安装环境 生成makefile
​	make       生成.o和可执行文件
​	sudo make install  将必要的资源拷贝至系统指定目录
	进入sample,运行demo
    编译使用库的.c的时候  需要添加-levent选项          ./a静态库  ./o动态库
    看库名 libevent.so---->/usr/local/lib/
libevent框架
创建event_base;
	struct event_base * event_base_new(void);
	struct event_base * bas=event_base_new();
创建 事件event;
	常规事件 event;--->event_new();
	带缓冲的事件  bufferevent;--->bufferevent_socket_new();
将事件添加到base上;
	int event_add(struct event* ev,const struct timeval*tv );
循环监听事件满足;
	int event_base_dispatch(struct event_base* base);
释放event——base;
	event_base_free(base);
libevent 常规事件
创建事件
	struct event* event_new(struct event_base* base,evutil_socket_t fd,
		short what,event_callback_fn cb;void * arg);
	fd:绑定在事件上的文件描述符
    what:对应发生的事件(响应)(r,w,e) --EV_READ--EV_WRITE--EV_PERSIST持续触发
    cb:一旦事件满足监听条件,回调的函数。
typedef void (*event_callback_fn) (evutil_sockt fd,short,void*);

将事件添加到event_base上面:
	int event_add(struct event* ev,const struct timeval* tv)
    	ev:event_new()的返回值
		tv:NULL,
-------对应有一个event_del();----用的少,一般不用就直接销毁就可以了
销毁事件
    int event_free(struct event* ev);
libevent 未决和非未决

未决:有资格被处理,但是没有被处理

非未决:没有资格处理

libevent bufferevent

在这里插入图片描述

创建和释放事件
创建:
struct bufferevent* bufferevent_socket_new(struct event_base *base,evutil_socket_t fd,enum buferrevent_options) 
	base:event_base
	fd:封装到bufferevent内部的fd
	option:BEV_OPT_CLOSE_ON_FREE
	返回:成功创建的bufferevent事件对象
销毁:
      void bufferevent_free()
给读写缓冲区设置回调
对比 event   event_new(fd,callback);event_add()---挂到event_base上
    	    bufferevent_socket_new(fd,)  +  bufferevent_setcb(callback);
设置:
    void bufferevent_setcb(struct bufferevent* bufev,  
                          	bufferevent_data_cb readcb,  //读回调
                          	bufferevent_data_cb writecb, //写回调
                          	bufferevent_data_cb eventcb,  //设置回调【可设置NULL】
                          	void *cbarg)				//参数
回调函数:
 ()typedf void(*bufferevent_data_cb)(struct bufferevent* bev,void * ctx);
	void read_cb(struct bufferevent* bev,void * ctx){
        ......
        bufferevent_read();
    }
	size_t bufferevent_read(struct bufferevent* bufev,void* buf,size_t busize)
    size_t bufferevent_read(struct bufferevent* bufev,const void* buf,size_t busize)   (事件)typedf void(*bufferevent_event_cb)(struct bufferevent* bev,short ev,void * ctx);    		events:  BEV_EVENT_CONNETED
缓冲区的设置
void bufferevent_enable(struct bufferevent* bufev,short events)
    			 disable
   	events:EV_READ  EV_WERITE  EV_READ|EV_WRITE
 默认bufferevent写缓冲是enable,而  读缓冲 是disable;
客户端
	connct();-------------------->
	int bufferevetn_socket_connet(
		struct buuferevent* bev,struct sockaddr* address,int addrlen)

服务端

	socke(),bind(),listen(),accept();------------------->
    #include<event2/listener.h>
    struct evconnlisterner* evconnlistner_new_bind(
    	struct event_base* base,
    	evconnlistener_cb cb, // 回调函数
    	void * ptr,			//  回调函数的参数
    	unsigned flags,		//LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE
    	int backlog,		//lieten的第二个参数 -1表示默认最大值
    	const struct sockaddr* sa  //服务器地址
    	int socklen);
	返回一个成功创建的监听器。
   typedef void (*evconnlistener_cb)(
    	struct evconnlistener* listener,  //
    	evutil_socket_t sock,		//用于通信的文件描述符
    	struct sockaddr* addr,		//客服端的地址结构
    	int len,					//
    	void * ptr)					//外部ptr传递进来的值
服务器流程
1.创建event_base
2.创建服务器连接监听器  evconnlister_new_bind();
3.在 evconnlister_new_bind 的回调函数中,处理接受连接后的操作
4.回调函数被使用,说明有一个新的客户端来连接上来,会得到一个新的fd,用于客户端通讯(读,写);
5.创建bufferevent事件对象  bufferevent_socket_new(),将fd封装到这个事件对象中
6.使用bufferevent_setcb给这个事件对象的read write event设置回调
7.设置bufferevent的读写缓冲区enable\diable
8.接受、发送数据  bufferevent_read()/bufferevent_write();
9.启动循环监听
10.释放资源
客服端流程
1.创建event_base
2.使用bufferevent_socket_new()创建一个用跟服务器通讯的bufferevent事件对象
3.使用bufferevent_socket_connect()连接服务器
4.使用bufferevent_setcb()给bufferevnet对象的read  write event 设置回调
5.设置bufferevent对象的缓冲区 enable \disable
6.接受、发送数据  bufferevent_read()/bufferevent_write();
7.启动循环监听
8.释放资源
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值