libevent的使用方法--回显服务器的简单实例
#include <event.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h> #define SERVER_PORT 8080
int debug = 0; struct client {
int fd;
struct bufferevent *buf_ev;
}; int setnonblock(int fd)
{
int flags; flags = fcntl(fd, F_GETFL);
flags |= O_NONBLOCK;
fcntl(fd, F_SETFL, flags);
} void buf_read_callback(struct bufferevent *incoming,
void *arg)
{
struct evbuffer *evreturn;
char *req; req = evbuffer_readline(incoming->input);
if (req == NULL)
return; evreturn = evbuffer_new();
evbuffer_add_printf(evreturn,"You said %s\n",req);
bufferevent_write_buffer(incoming,evreturn);
evbuffer_free(evreturn);
free(req);
} void buf_write_callback(struct bufferevent *bev,
void *arg)
{
} void buf_error_callback(struct bufferevent *bev,
short what,
void *arg)
{
struct client *client = (struct client *)arg;
bufferevent_free(client->buf_ev);
close(client->fd);
free(client);
} void accept_callback(int fd,
short ev,
void *arg)
{
int client_fd;
struct sockaddr_in client_addr;
socklen_t client_len = sizeof(client_addr);
struct client *client; client_fd = accept(fd,
(struct sockaddr *)&client_addr,
&client_len);
if (client_fd < 0)
{
warn("Client: accept() failed");
return;
} setnonblock(client_fd); client = calloc(1, sizeof(*client));
if (client == NULL)
err(1, "malloc failed");
client->fd = client_fd; client->buf_ev = bufferevent_new(client_fd,
buf_read_callback,
buf_write_callback,
buf_error_callback,
client); bufferevent_enable(client->buf_ev, EV_READ);
} int main(int argc,
char **argv)
{
int socketlisten;
struct sockaddr_in addresslisten;
struct event accept_event;
int reuse = 1; event_init(); socketlisten = socket(AF_INET, SOCK_STREAM, 0); if (socketlisten < 0)
{
fprintf(stderr,"Failed to create listen socket");
return 1;
} memset(&addresslisten, 0, sizeof(addresslisten)); addresslisten.sin_family = AF_INET;
addresslisten.sin_addr.s_addr = INADDR_ANY;
addresslisten.sin_port = htons(SERVER_PORT); if (bind(socketlisten,
(struct sockaddr *)&addresslisten,
sizeof(addresslisten)) < 0)
{
fprintf(stderr,"Failed to bind");
return 1;
} if (listen(socketlisten, 5) < 0)
{
fprintf(stderr,"Failed to listen to socket");
return 1;
} setsockopt(socketlisten,
SOL_SOCKET,
SO_REUSEADDR,
&reuse,
sizeof(reuse)); setnonblock(socketlisten); event_set(&accept_event,
socketlisten,
EV_READ|EV_PERSIST,
accept_callback,
NULL); event_add(&accept_event,
NULL); event_dispatch(); close(socketlisten); return 0;
}
下面讨论各个函数及其操作:
1、main():主函数创建用来监听连接的套接字,然后创建 accept() 的回调函数以便通过事件处理函数处理每个连接。
2、accept_callback():当接受连接时,事件系统调用此函数。此函数接受到客户端的连接;添加客户端套接字信息和一个 bufferevent 结构;在事件结构中为客户端套接字上的读/写/错误事件添加回调函数;作为参数传递客户端结构(和嵌入的 eventbuffer 和客户端套接字)。每当对应的客户端套接字包含读、写或错误操作时,调用对应的回调函数。
3、buf_read_callback():当客户端套接字有要读的数据时调用它。作为回显服务,此函数把 "you said..." 写回客户端。套接字仍然打开,可以接受新请求。
4、buf_write_callback():当有要写的数据时调用它。在这个简单的服务中,不需要此函数,所以定义是空的。
5、buf_error_callback():当出现错误时调用它。这包括客户端中断连接。在出现错误的所有场景中,关闭客户端套接字,从事件列表中删除客户端套接字的事件条目,释放客户端结构的内存。
5、setnonblock():设置网络套接字以开放 I/O。
当客户端连接时,在事件队列中添加新事件以处理客户端连接;当客户端中断连接时删除事件。在幕后,libevent 处理网络套接字,识别需要服务的客户端,分别调用对应的函数。为了构建这个应用程序,需要编译 C 源代码并添加 libevent 库:$ gcc -o basic basic.c -levent。
$ telnet localhost 8080
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Hello!
You said Hello!
测试的时候可以使用上面的方法!
libevent的使用方法--回显服务器的简单实例的更多相关文章
- epoll 回显服务器源码
在写epoll回显服务器代码之前,可以先看看上一篇文章:select poll epoll三者之间的比较.最近在继续学习网络编程中的服务端编程中,了解到很多网游服务器是在IOMP(IO完成端口)框架下 ...
- 基于TCP协议 I/O多路转接(select) 的高性能回显服务器客户端模型
服务端代码: myselect.c #include <stdio.h> #include <netinet/in.h> #include <arpa/inet.h> ...
- jquery load 方法回显数据
使用jQuery对象.load()方法 load() 方法的作用是可以通过 AJAX 请求从服务器加载数据,并把返回的数据直接放置到指定的元素中. 该方法使用起来非常简单,大大简化了ajax开发 语法 ...
- Python网络编程——编写一个简单的回显客户端/服务器应用
今天将python中socket模块的基本API学习完后,照着书上的实例编写一个套接字服务器和客户端.采用python3.5版本,在注释中会标明python2和python3的不同之处. 1.代码 ( ...
- 捅伊朗黑客PP — 后台登陆POST+错误回显 注入
看了一个泰国政府的网站被伊朗的黑客挂页,上面写着“Your Box 0wn3z By Behrooz_Ice – Q7x -Sha2ow -Virangar -Ali_Eagle -iman_takt ...
- HTML、jsp页面中radio,checkbox,select数据回显功能,默认被选中问题
最近常常遇到各种复选框.单选框.下拉框的默认被选中的问题,开始也是绞尽脑汁的想办法,今天写一篇学习总结的博文来写一下学习总结. 单选框(radio)默认被选中: 一.jstl技术进行回显 <in ...
- 【渗透测试】如何利用burpsuite测试无回显漏洞
前面的文章讲了在windows和linux上的不同的无文件渗透测试的方法,那么这篇文章给大家讲解如何在漏洞没有回显的情况下,利用burpsuite自带插件进行测试的方式. 首先我们稍微提一下有哪些无回 ...
- 08_springmvc数据回显和@ModelAttribute注解详解
一.数据回显 提交后,如果出现错误,将刚才提交的数据回显到刚才的提交页面. 二.pojo数据回显方法 1.springmvc默认对pojo数据进行回显. pojo数据传入controller方法后,s ...
- EasyUI加zTree使用解析 easyui修改操作的表单回显方法 验证框提交表单前验证 datagrid的load方法
带参提交一次查询,从服务器加载新数据.这是一个神奇的方法 $('#dg').datagrid('load',{ code: '01', name: 'name01' }); easyui修改操作的回显 ...
随机推荐
- bzoj3632
裸的最大团,随机化大法好 多次随机出一个选择顺序然后贪心即可 ..,..] of boolean; a:..] of longint; v:..] of boolean; n,m,i,j,x,y,an ...
- nginx反向代理的简单配置
有两台机器A和B. A上边是nginx,B上边是tomcat. 现在要通过A的反向代理功能,通过A的nginx访问到B的tomcat. 首先tomcat已经配置好,并且正确启动,可访问. ...
- PhoneGap 安装体验
npm -v #显示版本,检查npm 是否正确安装. npm install express #安装express模块 npm install -g express #加上 -g 启用global安装 ...
- oracle等待事件以及解决方案
我们可以通过视图v$session_wait来查看系统当前的等待事件,以及与等待事件相对应的资源的相关信息,从而可确定出产生瓶颈的类型及其对象. v$session_wait的p1.p2.p3告诉我们 ...
- Java基础——I/O
文本I/O与二进制I/O 在计算机中所有的文件都是以二进制的形式来存储的,所以本质上所有的文件都是二进制文件. 文本I/O建立在二进制I/O的基础之上,它能提供字符层次的编码和解码的抽象,在写入一个字 ...
- Top Android App使用的组件 2
微信_355 SQLCipher:info.guardianproject.database:Android数据库加密 微博_650 点信传媒:cn.dx:广告平台 Apache HttpClient ...
- MySQL备份与复制
1.二进制日志 二进制日志记录了数据库的所有改变,使得任何slave都可以执行相同的更新.一般来说,开启二进制日志大概会有1%的性能损耗,它有两个重要的使用场景: (1)备份:在某个时间点t作了一次备 ...
- [Papers]NSE, $\n u_3$, Lebesgue space, [Pokorny, EJDE, 2003; Zhou, MAA, 2002]
$$\bex \n u_3\in L^p(0,T;L^q(\bbR^3)),\quad \frac{2}{p}+\frac{3}{q}=\frac{3}{2},\quad 2\leq q\leq \i ...
- jQuery 遍历 - parent() 方法
ylbtech-jQuery-sizzle:jQuery 遍历 - parent() 方法 parent() 获得当前匹配元素集合中每个元素的父元素,使用选择器进行筛选是可选的. 1.A,jQuer ...
- longest common str
#include <vector> #include <iostream> #include <string> using namespace std; int l ...