我承認(rèn)這篇文章有點(diǎn)標(biāo)題黨,呵呵。其實(shí)就是一個(gè)能和服務(wù)器建立全雙工通信的客戶端而已,用網(wǎng)絡(luò)庫libevent實(shí)現(xiàn)。
從這里也可以看出,同樣的功能,分別用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>
//發(fā)生了致命錯(cuò)誤,輸入錯(cuò)誤信息,退出程序
void error_quit(const char *str)
{
perror(str);
exit(1);
}
//連接狀態(tài)改變時(shí)回調(diào)的函數(shù)
void eventcb(struct bufferevent *bev, short events, void *ptr)
{
struct event_base *tbase = (struct event_base*)ptr;
//如果不是連接成功的消息,就停止事件循環(huán)
if ( !(events & BEV_EVENT_CONNECTED) )
{
bufferevent_free(bev);
event_base_loopbreak(tbase);
printf("The connect have been shutdown: %X\n", events);
}
}
//服務(wù)器傳信息過來了
void sockreadcb(struct bufferevent *bev, void *ptr)
{
struct evbuffer *input = bufferevent_get_input(bev);
evbuffer_write(input, STDOUT_FILENO);
}
//標(biāo)準(zhǔn)輸入傳消息過來了
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();
//連接服務(wù)器并監(jiān)聽
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);
//監(jiān)聽標(biāo)準(zhǔn)輸入
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);
//開始事件循環(huán)
event_base_dispatch(base);
return 0;
}
編譯與運(yùn)行命令:
gcc mytelnet.c -o mytelnet -levent
./mytelnet 127.0.0.1 8877
用于測(cè)試的服務(wù)器:
http://blog.csdn.net/aaa20090987/article/details/8769585
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元

