#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <signal.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <event2/bufferevent.h>
#include <event2/buffer.h>
#include <event2/listener.h>
#include <event2/util.h>
#include <event2/event.h>
//端口
static const int PORT = 8888;
//数据读取缓存
static unsigned char read_buffer[1024];
static void on_write(struct bufferevent *, void *);
static void on_read(struct bufferevent *, void *);
static void on_event(struct bufferevent *, short, void *);
int main(int argc, char **argv)
{
//libevent实例
struct event_base *base;
//internet环境下套接字的地址形式
struct sockaddr_in sockaddr;
//创建一个event_base
base = event_base_new();
if (!base)
{
fprintf(stderr, "Could not initialize libevent!\n");
return 1;
}
//初始化sockaddr,全部置为0 第一个参数:数组起始地址 第二个参数:设置数组每个字节的值 第三个参数:数组的长度(字节数)
memset(&sockaddr, 0, sizeof(sockaddr));
//将一个IP字符串转化为一个网络字节序的整数值
sockaddr.sin_addr.s_addr = inet_addr("192.168.100.100");
//设置协议簇 AF_INET表示TCP/IP协议
sockaddr.sin_family = AF_INET;
//设置端口 将端口号由主机字节序转换为网络字节序的整数值
sockaddr.sin_port = htons(PORT);
//创建bufferevent上下文, BEV_OPT_CLOSE_ON_FREE:清理bufferevent时关闭socket
struct bufferevent *bev = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE);
if (bev == NULL)
{
fprintf(stderr, "socket init failed\n");
return 1;
}
//设置回调函数
bufferevent_setcb(bev, on_read, on_write, on_event, NULL);
//连接服务端
int flag = bufferevent_socket_connect(bev, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
if (flag == -1)
{
fprintf(stderr, "connect failed\n");
return 1;
}
//添加监控事件
bufferevent_enable(bev, EV_READ | EV_WRITE);
//启动事件循环
event_base_dispatch(base);
//释放资源
event_base_free(base);
printf("done\n");
return 0;
}
//打印16进制
void show_hex_string(size_t content_size)
{
for (int i = 0; i < content_size; i++)
{
printf("%.2x", read_buffer[i]);
}
printf("\n");
}
static void on_read(struct bufferevent *bev, void *user_data)
{
memset(read_buffer, 0x00, sizeof(read_buffer));
//获取输入缓冲区中的数据(数据未移走)
struct evbuffer *input = bufferevent_get_input(bev);
//返回evbuffer的字节数length
size_t content_size = evbuffer_get_length(input);
if (content_size > 0)
{
//从bev中读取size个字节的数据
bufferevent_read(bev, read_buffer, content_size);
show_hex_string(content_size);
}
}
static void on_write(struct bufferevent *bev, void *user_data)
{
}
static void on_event(struct bufferevent *bev, short events, void *user_data)
{
switch (events)
{
case BEV_EVENT_EOF:
printf("Connection closed.\n");
break;
case BEV_EVENT_ERROR:
printf("Got an error on the connection: %s\n", strerror(errno));
break;
case BEV_EVENT_CONNECTED:
printf("Connect success\n");
return;
default:
break;
}
bufferevent_free(bev);
}