-
Notifications
You must be signed in to change notification settings - Fork 0
/
libevent_client.c_bkp
executable file
·107 lines (93 loc) · 3.39 KB
/
libevent_client.c_bkp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include <sys/socket.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <event.h>
#include <event2/event.h>
#include <event2/bufferevent.h>
/* 发生了致命错误,输入错误信息,退出程序 */
void error_quit(const char *str)
{
/* perror()将上一个函数发生错误的原因输出到标准错误(stderr);
参数 s 所指的字符串会先打印出,后面再加上错误原因字符串;
此错误原因依照全局变量 errno 的值来决定要输出的字符串。
*/
perror(str);
exit(1);
}
/* 事件回调函数,连接状态改变时回调的函数 */
void event_cb(struct bufferevent *bev, short events, void *ptr)
{
struct event_base *tbase = (struct event_base*)ptr;
if ( events & BEV_EVENT_CONNECTED){
/* We're connected to server. Ordinarily we'd do
something here, like start reading or writing. */
printf("Server is connected!\n");
}else { //如果连接不成功的消息,就停止事件循环
bufferevent_free(bev);
event_base_loopbreak(tbase);
printf("The connect have been shutdown: %X\n", events);
}
}
/* 服务器传信息过来了
this callback is invoked when there is data to read on bev.
*/
void sock_readcb(struct bufferevent *bev, void *ptr)
{
struct evbuffer *input = bufferevent_get_input(bev);
evbuffer_write(input, STDOUT_FILENO);
}
/* 标准输入传消息过来了 */
void std_readcb(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 <IP Address> <Port>");
}
/* 初始化连接地址 */
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons( atoi(argv[2]) );
/*inet_pton 处理IPv4,将“点分十进制” -> “整数 */
res = inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
if( res != 1 ){
error_quit("inet_pton error");
}
base = event_base_new();
/* 连接服务器并监听 */
//bufferevent_socket_new创建基于套接字的bufferevent, 参数为-1 表示并不为此 bufferevent 设置 socket
if ((sockbev = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE)) == NULL){
error_quit("bufferevent_socket_new error");
}
// 建立连接,连接成功返回 0 失败返回 -1
res = bufferevent_socket_connect(sockbev, (struct sockaddr *)&servaddr, sizeof(servaddr));
if ( res < 0 ){
bufferevent_free(sockbev);
error_quit("connect error");
}
//为bufferevent event设置回调函数
bufferevent_setcb(sockbev, sock_readcb, NULL, event_cb, (void*)base);
//设置watermark
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, std_readcb, NULL, NULL, (void*)sockbev);
bufferevent_enable(stdbev, EV_READ);
bufferevent_enable(stdbev, EV_WRITE);
//开始事件循环
event_base_dispatch(base);
return 0;
}