windows使用libevent

// udp recv
#define _CRT_SECURE_NO_WARNINGS
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define _CRT_SECURE_NO_DEPRECATE
#define _CRT_NONSTDC_NO_DEPRECATE

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#pragma comment(lib, "ws2_32")

#define PORT 8000

#define OutErr(a) std::cout << (a) << std::endl << "出错代码:" \
					<< WSAGetLastError() << std::endl << "出错文件:" \
					<< __FILE__ << std::endl << "出错行数:"\
					<< __LINE__ << std::endl \

#define OutMsg(a) std::cout << (a) << std::endl; 

void eventCallback(intptr_t fd, short ev, void* user);

SOCKET initSocket()
{
	SOCKET server = socket(AF_INET, SOCK_DGRAM, 0);
	if (server == INVALID_SOCKET) {
		OutErr("WSASocket error.");
		return INVALID_SOCKET;
	}

	struct sockaddr_in servAddr;
	servAddr.sin_family = AF_INET;
	servAddr.sin_port = htons(PORT);
	servAddr.sin_addr.s_addr = inet_addr("127.0.0.1");

	if (bind(server, (struct sockaddr*)&servAddr, sizeof(servAddr)) < 0) {
		OutErr("bind Failed!");
		goto error;
	}
	return server;

error:
	closesocket(server);
	return INVALID_SOCKET;
}

int main()
{
	WSADATA wsaData;
	WORD sockVersion = MAKEWORD(2, 2);
	if (WSAStartup(sockVersion, &wsaData)) {
		printf("%s() WSAStartup error. [%d, %s]\n", __func__, errno, strerror(errno));
		return 0;
	}
    
	SOCKET server = initSocket();
	if (server == INVALID_SOCKET) {
		return 0;
	}
	// 设置socket 非阻塞属性
	u_long isNonBlock = 1;
	ioctlsocket(server, FIONBIO, &isNonBlock);

	struct event_base* base = event_base_new();
	assert(base != nullptr);
	printf("IO模型: %s\n", event_base_get_method(base));

	struct event* readEvent = event_new(base, server, EV_READ | EV_PERSIST | EV_ET, eventCallback, (void *)base);
	assert(event_add(readEvent, nullptr) == 0);

	event_base_dispatch(base);

	closesocket(server);
	WSACleanup();
	system("pause");
	return 0;
}

void eventCallback(intptr_t fd, short ev, void* user)
{
	static char* buf = nullptr;
	uint32_t size = 0;
	static char stackBuf[64] = { 0 };	// 将buf大小变小会在recvfrom处报错10040,原因是udp需要一次把数据读完
	char errbuf[32] = { 0 };

	buf = stackBuf;
	size = sizeof(stackBuf);

	if (ev == EV_READ) {
		sockaddr_in addr;
		int len = sizeof(sockaddr_in);
		if (getsockname(fd, (sockaddr*)&addr, &len)) {
			printf("getsockname error. %d\n", WSAGetLastError());
		} else {
			printf("local [%s:%d] ", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
		}

		u_long availableSize = 0;
		if (ioctlsocket(fd, FIONREAD, &availableSize))
		{
			printf("ioctlsocket error. %d\n", WSAGetLastError());
		}
		else
		{
			printf(", availableSize %lu ", availableSize);
		}

		if (availableSize > 0) {
			buf = (char*)malloc(availableSize + 1);
			if (buf)
			{
				size = availableSize + 1;
			}
			else
			{
				buf = stackBuf;
			}
		}

		printf("recvfrom -----> ");
		memset(buf, 0, size);
		int readSize = recvfrom(fd, buf, size, 0, (sockaddr*)&addr, &len);
		if (readSize > 0) {
			printf("%s() recvfrom [%s:%d]: %s\n", __FUNCTION__, inet_ntoa(addr.sin_addr), ntohs(addr.sin_port), buf);
		} else {
			printf("%d\n", WSAGetLastError());
		}
	}

	if (buf != stackBuf) {
		printf("free %p\n", buf);
		free(buf);
	}
}
// udp send
#define _CRT_SECURE_NO_WARNINGS
#define _WINSOCK_DEPRECATED_NO_WARNINGS

#include "event.h"
#include 
#include 
#include 
#include 
#include 
#include 

#pragma comment(lib,"ws2_32.lib")

#define PEER_PORT 8000

#define OutErr(a) std::cout << (a) << std::endl << "出错代码:" \
					<< WSAGetLastError() << std::endl << "出错文件:" \
					<< __FILE__ << std::endl << "出错行数:"\
					<< __LINE__ << std::endl \

#define OutMsg(a) std::cout << (a) << std::endl; 

void OnTime(intptr_t sock, short event_value, void* arg) {
    std::string buf = "Hello World";

    struct sockaddr_in servAddr;
    servAddr.sin_family = AF_INET;
    servAddr.sin_port = htons(PEER_PORT);
    servAddr.sin_addr.s_addr = inet_addr("127.0.0.1");

    int sendSize = ::sendto(sock, buf.c_str(), buf.length(), 0, (sockaddr*)&servAddr, sizeof(sockaddr_in));
    if (sendSize < 0) {
        std::cout << WSAGetLastError();
        std::cout << " errno: " << errno << ", " << strerror(errno) << std::endl;
        return;
    }
    std::cout << "sendto size: " << sendSize << std::endl;

    std::cout << "content: " << buf << std::endl;

    timeval tv;
    tv.tv_sec = 1;
    tv.tv_usec = 0;
    event_add((struct event*)arg, &tv);
}

int main()
{
    WSADATA wsaData;
    WORD sockVersion = MAKEWORD(2, 2);
    if (WSAStartup(sockVersion, &wsaData)) {
        printf("%s() WSAStartup error. [%d, %s]\n", __func__, errno, strerror(errno));
        return 0;
    }

    SOCKET local = socket(AF_INET, SOCK_DGRAM, 0);
    if (local == INVALID_SOCKET) {
        OutErr("WSASocket error.");
        return INVALID_SOCKET;
    }

    struct sockaddr_in servAddr;
    servAddr.sin_family = AF_INET;
    servAddr.sin_port = htons(PEER_PORT);
    servAddr.sin_addr.s_addr = htonl(INADDR_ANY);

    event_init();
    struct event ev_time;
    event_set(&ev_time, local, 0, OnTime, &ev_time);
    struct timeval tv;
    tv.tv_sec = 1;
    tv.tv_usec = 0;
    event_add(&ev_time, &tv);
    event_dispatch();

    system("pause");
    WSACleanup();
    return 0;
}
运行截图

windows使用libevent_第1张图片

你可能感兴趣的:(c/c++,c++,网络IO)