windows libevent使用 客户端+服务端

本文详细介绍了在Windows平台上如何使用libevent库创建一个服务端和客户端应用程序。内容涵盖libevent的安装配置,服务端的socket监听,客户端的连接发起,以及数据收发的实现过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

服务端:

// ConsoleApplication5.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <event2/listener.h>
#include <event2/event.h>
#include <event2/event_struct.h>
#include <event2/bufferevent.h>
#include <event2/buffer.h>
#include <signal.h>

#pragma comment(lib, "libevent.lib")
#pragma comment(lib, "libevent_core.lib")
#pragma comment(lib, "libevent_extras.lib")
#pragma comment(lib, "ws2_32.lib")

static const char MESSAGE[] = "hello new connection!";

void read_cb(struct bufferevent *bev, void *ctx)
{
	struct evbuffer* input = bufferevent_get_input(bev);
	char buffer[1024] = { 0 };
	int n = 0;
	while ((n = evbuffer_remove(input, buffer, sizeof(buffer))) > 0)
	{
		printf("read_cb:%s\n", buffer);
	}

	char* msg = "我是服务器发来的信息";
	bufferevent_write(bev, msg, strlen(msg));
}

void write_cb(struct bufferevent *bev, void *ctx)
{
	struct evbuffer* output = bufferevent_get_output(bev);
	if (evbuffer_get_length(output) == 0)
	{
		//bufferevent_free(bev);
	}
}

void event_cb(struct bufferevent *bev, short what, void *ctx)
{
	if (what & BEV_EVENT_EOF)
	{
		printf("Connection closed.\n");
	}
	else if (what & BEV_EVENT_ERROR)
	{
		char sz[100] = { 0 };
		strerror_s(sz, 100, errno);
		printf("Got an error on the connection: %s\n",
			sz);/*XXX win32*/
	}
	/* None of the other events can happen here, since we haven't enabled
	* timeouts */
	bufferevent_free(bev);
}

void listener_cb(struct evconnlistener *listener, evutil_socket_t fd, struct sockaddr *sa, int socklen, void *user_data)
{
	struct event_base* base = (struct event_base*)user_data;

	struct bufferevent* bev = NULL;
	bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);

	bufferevent_setcb(bev, read_cb, write_cb, event_cb, NULL);

	bufferevent_enable(bev, EV_WRITE | EV_READ);

	//bufferevent_disable(bev, EV_READ);

	bufferevent_write(bev, MESSAGE, strlen(MESSAGE));
}

void signal_cb(evutil_socket_t fd, short events, void *user_data)
{
	struct event_base* base = (struct event_base*)user_data;

	struct timeval delay = { 2, 0 };

	event_base_loopexit(base, &delay);
}

int _tmain(int argc, _TCHAR* argv[])
{
	WSADATA wsa_data;
	WSAStartup(MAKEWORD(2,2), &wsa_data);

	/*struct event_config* cfg = event_config_new();
	event_config_set_flag(cfg, EVENT_BASE_FLAG_STARTUP_IOCP); 
	struct event_base* base = event_base_new_with_config(cfg);
	event_config_free(cfg);*/

	struct event_base* base = event_base_new();
	//const char* method = event_base_get_method(base);

	struct sockaddr_in listen_addr = { 0 };
	memset(&listen_addr, 0, sizeof(listen_addr));
	listen_addr.sin_addr.s_addr = htonl(0x7f000001);
	//inet_pton(AF_INET, "127.0.0.1", &listen_addr.sin_addr.s_addr);
	listen_addr.sin_family = AF_INET;
	listen_addr.sin_port = htons(8981);

	struct evconnlistener* listener = evconnlistener_new_bind(base,
		listener_cb,
		(void*)base, 
		LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE,
		-1, 
		(const sockaddr*)&listen_addr, 
		sizeof(listen_addr));

	//struct event * signal_event = evsignal_new(base, SIGINT, signal_cb, (void*)base);
	//event_add(signal_event, NULL);

	event_base_dispatch(base);

	evconnlistener_free(listener);

	//event_free(signal_event);

	event_base_free(base);

	WSACleanup();

	return 0;
}

客户端:

// client.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include <event2/listener.h>
#include <event2/event.h>
#include <event2/event_struct.h>
#include <event2/bufferevent.h>
#include <event2/buffer.h>

#pragma comment(lib, "libevent.lib")
#pragma comment(lib, "libevent_core.lib")
#pragma comment(lib, "libevent_extras.lib")
#pragma comment(lib, "ws2_32.lib")


void read_cb(struct bufferevent *bev, void *ctx)
{
	char* msg = "林子大了什么鸟都有";
	struct evbuffer* input = bufferevent_get_input(bev);
	struct evbuffer* output = bufferevent_get_output(bev);

	char buffer[1024] = { 0 };
	int n = 0;
	while ( (n = evbuffer_remove(input, buffer, sizeof(buffer))) > 0 )
	{
		printf("read_cb:%s\n", buffer);
	}

	//bufferevent_write(bev, msg, strlen(msg));

	evbuffer_add(output, msg, strlen(msg));
}


void write_cb(struct bufferevent *bev, void *ctx)
{
	struct evbuffer *output = bufferevent_get_output(bev);
	if (evbuffer_get_length(output) == 0)
	{
		//printf("flushed answer\n");
		//bufferevent_free(bev);
	}
}

void event_cb(struct bufferevent *bev, short what, void *ctx)
{
	if (what & BEV_EVENT_EOF)
	{
		printf("Connection closed.\n");
	}
	else if (what & BEV_EVENT_ERROR)
	{
		char sz[100] = { 0 };
		strerror_s(sz, 100, errno);
		printf("Got an error on the connection: %s\n",
			sz);/*XXX win32*/
	}
	else if (what & BEV_EVENT_TIMEOUT)
	{
		printf("Connection timeout.\n");
	}
	else if (what & BEV_EVENT_CONNECTED)
	{
		printf("Connect succeed\n");
		//客户端链接成功后,给服务器发送第一条消息  
		char *reply_msg = "I receive a message from client";
		bufferevent_write(bev, reply_msg, strlen(reply_msg));
		return;
	}
	/* None of the other events can happen here, since we haven't enabled
	* timeouts */
	bufferevent_free(bev);
}


int _tmain(int argc, _TCHAR* argv[])
{
	WSADATA wsa_data;
	WSAStartup(MAKEWORD(2, 2), &wsa_data);

	struct sockaddr_in addr = { 0 };
	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = htonl(0x7f000001);
	//inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr.s_addr);
	addr.sin_port = htons(8981);

	struct event_base* base = event_base_new();

	bufferevent* bev = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE);

	bufferevent_setcb(bev, read_cb, write_cb, event_cb, NULL);

	int i = bufferevent_socket_connect(bev, (const sockaddr*)&addr, sizeof(addr));

	i = bufferevent_enable(bev, EV_READ | EV_WRITE);

	i = event_base_dispatch(base);

	//bufferevent_free(bev);

	event_base_free(base);

	return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值