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修改操作的回显 ...
随机推荐
- codevs 1197 Vigenère密码
开始做NOIP啦.. #include<iostream> #include<cstdio> #include<cstring> #include<algor ...
- Python - re - 正则表达式 - 怎么用
<python cookbook> - 1.18 - 一次完成多个替换 这个blog介绍正则,写得不错,而且,一如既往的‘长’. 1. re.escape(string) THIS,说明函 ...
- ORACLE远程连接数据库
1. sqlplus sqlnet.ora 文件格式NAMES.DIRECTORY_PATH= (TNSNAMES,HOSTNAME).客户端就会首先在tnsnames.ora文件中找orcl的记录. ...
- 一天一个Java基础——泛型
这学期的新课——设计模式,由我仰慕已久的老师传授,可惜思维过快,第一节就被老师挑中上去敲代码,自此在心里烙下了阴影,都是Java基础欠下的债 这学期的新课——算法设计与分析,虽老师不爱与同学互动式的讲 ...
- 【jQuery】总结:筛选器、控制隐藏、操作元素style属性
筛选器 -> http://blog.csdn.net/lijinwei112/article/details/6938134 常用到的: $("tr[id=ac_"+id+ ...
- 【字符串处理】HDOJ-1020-Encoding
[题目链接:HDOJ-1020] 相邻字符,两两比较. #include<cstdio> #include<cstring> ; char sr[MAXN]; int main ...
- Struts2的OGNL标签详解
一.Struts2可以将所有标签分成3类: UI标签:主要用于生成HTML元素的标签. 非UI标签:主要用于数据库访问,逻辑控制等标签. Ajax标签:用于Ajax支持的标签. 对于UI标签,则有可以 ...
- Java中的面向接口编程
面向接口编程是很多软件架构设计理论都倡导的编程方式,学习Java自然少不了这一部分,下面是我在学习过程中整理出来的关于如何在Java中实现面向接口编程的知识.分享出来,有不对之处还请大家指正. 接口体 ...
- solr4.2 solrconfig.xml配置文件简单介绍
对于solr4.x的每个core有两个很重要的配置文件:solrconfig.xml和schema.xml,下面我们来了解solrconfig.xml配置文件. 具体很详细的内容请细读solrcofi ...
- [转] “error LNK2019: 无法解析的外部符号”之分析
HiLoveS原文“error LNK2019: 无法解析的外部符号”之分析 最近在用VS 2008开发,初学遇到不少问题,最头疼的问题之一就是:LNK2019. 百度一下讲的并不够全面,反正都没解决 ...