用libevent实现简易的telnet

我承认这篇文章有点标题党,呵呵。其实就是一个能和服务器建立全双工通信的客户端而已,用网络库libevent实现。
从这里也可以看出,同样的功能,分别用epoll和libevent来比较,从代码量和代码清晰度来说,libevent完胜,呵呵。
上代码:
#include <sys/socket.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>

#include <event.h>
#include <event2/event.h>

//发生了致命错误,输入错误信息,退出程序
void error_quit(const char *str)
{
	perror(str);
	exit(1); 
}

//连接状态改变时回调的函数
void eventcb(struct bufferevent *bev, short events, void *ptr)
{
	struct event_base *tbase = (struct event_base*)ptr;
	//如果不是连接成功的消息,就停止事件循环
	if ( !(events & BEV_EVENT_CONNECTED) ) 
	{
		bufferevent_free(bev);
		event_base_loopbreak(tbase);
		printf("The connect have been shutdown: %X\n", events);
	} 
}

//服务器传信息过来了
void sockreadcb(struct bufferevent *bev, void *ptr)
{
	struct evbuffer *input = bufferevent_get_input(bev);
	evbuffer_write(input, STDOUT_FILENO);
}

//标准输入传消息过来了
void stdreadcb(struct bufferevent *bev, void *ptr)
{
	struct bufferevent *sockbev = (struct bufferevent*)ptr; 
	struct evbuffer *input = bufferevent_get_input(bev);
	bufferevent_write_buffer(sockbev, input);
}

int main(int argc, char **argv)
{
	struct sockaddr_in servaddr;
	struct event *shellev;
	int res;
	struct event_base *base;
	struct bufferevent *sockbev;
	struct bufferevent *stdbev;

	if( argc != 3 )
		error_quit("Using: mytelnet <Address> <Port>");

	memset(&servaddr, 0, sizeof(servaddr));    
	servaddr.sin_family = AF_INET;    
	servaddr.sin_port = htons( atoi(argv[2]) );    
	res = inet_pton(AF_INET, argv[1], &servaddr.sin_addr);  
	if( res != 1 )
		error_quit("inet_pton error");   

	base = event_base_new();

	//连接服务器并监听
	sockbev = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE);
	res = bufferevent_socket_connect(sockbev,
		(struct sockaddr *)&servaddr, sizeof(servaddr));
	if ( res < 0 ) 
		error_quit("connect error");

	bufferevent_setcb(sockbev, sockreadcb, NULL, eventcb, (void*)base);
	bufferevent_enable(sockbev, EV_READ);
	bufferevent_enable(sockbev, EV_WRITE);

	//监听标准输入
	stdbev = bufferevent_socket_new(base, STDIN_FILENO, BEV_OPT_CLOSE_ON_FREE);
	bufferevent_setcb(stdbev, stdreadcb, NULL, NULL, (void*)sockbev);
	bufferevent_enable(stdbev, EV_READ);
	bufferevent_enable(stdbev, EV_WRITE);

	//开始事件循环
	event_base_dispatch(base);

	return 0;
}
编译与运行命令:
gcc mytelnet.c -o mytelnet -levent
./mytelnet 127.0.0.1 8877
用于测试的服务器:http://blog.csdn.net/aaa20090987/article/details/8769585
posted @ 2013-06-07 20:16  爱生活,爱编程  阅读(497)  评论(1编辑  收藏  举报