用libevent实现简易的telnet

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

	char address[32] = { 0 };

	//DNS解析地址
	struct hostent *host = gethostbyname(argv[1]);
	memset(&servaddr, 0, sizeof(servaddr));      
	servaddr.sin_family = AF_INET;      
	servaddr.sin_port = htons( atoi(argv[2]) );

	res = inet_ntop(host->h_addrtype, host->h_addr, address, sizeof(address));
	if( res != 1 )  
		error_quit("inet_ntop error");     
	res = inet_pton(AF_INET, address, &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

你可能感兴趣的:(用libevent实现简易的telnet)