#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的使用方法--回显服务器的简单实例的更多相关文章

  1. epoll 回显服务器源码

    在写epoll回显服务器代码之前,可以先看看上一篇文章:select poll epoll三者之间的比较.最近在继续学习网络编程中的服务端编程中,了解到很多网游服务器是在IOMP(IO完成端口)框架下 ...

  2. 基于TCP协议 I/O多路转接(select) 的高性能回显服务器客户端模型

    服务端代码: myselect.c #include <stdio.h> #include <netinet/in.h> #include <arpa/inet.h> ...

  3. jquery load 方法回显数据

    使用jQuery对象.load()方法 load() 方法的作用是可以通过 AJAX 请求从服务器加载数据,并把返回的数据直接放置到指定的元素中. 该方法使用起来非常简单,大大简化了ajax开发 语法 ...

  4. Python网络编程——编写一个简单的回显客户端/服务器应用

    今天将python中socket模块的基本API学习完后,照着书上的实例编写一个套接字服务器和客户端.采用python3.5版本,在注释中会标明python2和python3的不同之处. 1.代码 ( ...

  5. 捅伊朗黑客PP — 后台登陆POST+错误回显 注入

    看了一个泰国政府的网站被伊朗的黑客挂页,上面写着“Your Box 0wn3z By Behrooz_Ice – Q7x -Sha2ow -Virangar -Ali_Eagle -iman_takt ...

  6. HTML、jsp页面中radio,checkbox,select数据回显功能,默认被选中问题

    最近常常遇到各种复选框.单选框.下拉框的默认被选中的问题,开始也是绞尽脑汁的想办法,今天写一篇学习总结的博文来写一下学习总结. 单选框(radio)默认被选中: 一.jstl技术进行回显 <in ...

  7. 【渗透测试】如何利用burpsuite测试无回显漏洞

    前面的文章讲了在windows和linux上的不同的无文件渗透测试的方法,那么这篇文章给大家讲解如何在漏洞没有回显的情况下,利用burpsuite自带插件进行测试的方式. 首先我们稍微提一下有哪些无回 ...

  8. 08_springmvc数据回显和@ModelAttribute注解详解

    一.数据回显 提交后,如果出现错误,将刚才提交的数据回显到刚才的提交页面. 二.pojo数据回显方法 1.springmvc默认对pojo数据进行回显. pojo数据传入controller方法后,s ...

  9. EasyUI加zTree使用解析 easyui修改操作的表单回显方法 验证框提交表单前验证 datagrid的load方法

    带参提交一次查询,从服务器加载新数据.这是一个神奇的方法 $('#dg').datagrid('load',{ code: '01', name: 'name01' }); easyui修改操作的回显 ...

随机推荐

  1. IIS Server is too busy 解决方法(IIS6)

    Server is too busy意思是服务器繁忙,资源不够用 为什么会出现这个问题呢? 因为服务器的配置不同,所能承受的压力不同. 而服务器默认对链接数,线程数等有设置,但这个设置太小,基本不够用 ...

  2. json转csv

    import re # csv格式 # 'k1,k2,k3\nv1,v2,v3\nv4,v5,v6\n' market_list_data = { "data": [ { &quo ...

  3. (转)HTTP协议详解

    引言 HTTP是一个属于应用层的面向对象的协议,由于其简捷.快速的方式,适用于分布式超媒体信息系统.它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展.目前在WWW中使用的是HTTP/1. ...

  4. Oracle 课程八之性能优化之Oracle SQL Trace

    一. SQL_TRACE 当SQL语句出现性能问题时,我们可以用SQL_TRACE来跟踪SQL的执行情况,通过跟踪,我们可以了解一条SQL或者PL/SQL包的运行情况,SQL_TRACE命令会将SQL ...

  5. HDU 5432 Pyramid Split

    题意:有n个底面是正方形的四棱锥,用一个水平截面将所有四棱锥分成两半,要求上一半体积的和等于下一半,求水平截面的高度,输出整数部分. 解法:二分截面高度.比赛的时候二分写不明白了orz…… 代码: # ...

  6. [Everyday Mathematics]20150110

    试证: $$\bex \vlm{n}\frac{\ln^2n}{n}\sum_{k=2}^{n-2}\frac{1}{\ln k\cdot \ln(n-k)}=1. \eex$$

  7. FTP文件上传与下载

    实现FTP文件上传与下载可以通过以下两种种方式实现(不知道还有没有其他方式),分别为:1.通过JDK自带的API实现:2.通过Apache提供的API是实现. 第一种方式:使用jdk中的ftpClie ...

  8. T-SQL 数据库笔试题

    1.说明:创建数据库 Create DATABASE database-name 2.说明:删除数据库 drop database dbname 3.说明:备份sql server --- 创建备份数 ...

  9. C++实现网格水印之调试笔记(六)——补充

    调用matlab生成的网格水印特征向量矩阵 从文件中读取的原始网格的特征向量矩阵 好吧,之前得出的结果不正确是因为代码写错了.因为实现论文中的提取方案时代码写错了,自己想了另外一个方法,结果方向两者在 ...

  10. 取消eclipse启动时的subclipse Usage弹窗

    取消windows–>perferences–>general–>startup and shutdown里最下面的Subclipse Usage report 勾选即可