From fdb5f15fef452376708fc1ae9d12ebecb0bf3d08 Mon Sep 17 00:00:00 2001 From: zcy <290198252@qq.com> Date: Mon, 14 Feb 2022 00:31:34 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0udp=20group?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/proto_debuger/udp_group_libevent.cpp | 130 ++++++++++++++++++ examples/proto_debuger/udp_group_libevent.h | 8 +- examples/proto_debuger/udp_libevent.cpp | 2 +- examples/proto_debuger/udp_libevent.h | 1 - 4 files changed, 134 insertions(+), 7 deletions(-) diff --git a/examples/proto_debuger/udp_group_libevent.cpp b/examples/proto_debuger/udp_group_libevent.cpp index 23ab8b80..51557a55 100644 --- a/examples/proto_debuger/udp_group_libevent.cpp +++ b/examples/proto_debuger/udp_group_libevent.cpp @@ -1,3 +1,133 @@ #include "udp_group_libevent.h" +#include "udp_group_libevent.h" +#include +#include +#include +#include +#ifdef __cplusplus +extern "C" { +#endif +#include +#include + +#ifdef __cplusplus +} +#endif +#define MSG_LEN 1024 + +static void read_cb(evutil_socket_t fd, short event, void* arg) { + UdpGroupLibevent* parent = (UdpGroupLibevent*)arg; + if (parent == nullptr) + return; + + char buf[MSG_LEN]; + int len; + int addr_len = sizeof(struct sockaddr); + struct sockaddr_in cli_addr; + + memset(buf, 0, sizeof(buf)); + len = recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr*)&cli_addr, &addr_len); + + if (len == -1) { + perror("recvfrom"); + } + else if (len == 0) { + printf("Connection Closed\n"); + } + else { + buf[len] = '\0'; + printf("recv[%s:%d]\n", buf, len); + // sendto(fd, buf, len, 0, (struct sockaddr*)&cli_addr, addr_len); + if (parent->OnReadHandle() != nullptr) { + UdpGroupLibevent::OnReadDataHandle p = parent->OnReadHandle(); + if (p) + p(buf, len, cli_addr); + } + } +} + +int UdpGroupLibevent::bind_socket(struct event* ev, const char* ip, uint16_t port) { + int sock_fd; + int flag = 1; + struct sockaddr_in local_addr; + + if ((nullptr == ip) || (nullptr == ev)) { + m_status = FAIL; + return -1; + } + + if ((sock_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + perror("socket"); + return -1; + } + + if (setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&flag, sizeof(flag)) < 0) { + perror("setsockopt"); + return 1; + } + memset(&local_addr, 0, sizeof(local_addr)); + local_addr.sin_family = AF_INET; + local_addr.sin_port = htons(port); + local_addr.sin_addr.s_addr = inet_addr(ip); + if (bind(sock_fd, (struct sockaddr*)&local_addr, sizeof(struct sockaddr)) < 0) { + perror("bind"); + return -1; + } + else { + printf("bind success, port[%d]\n", port); + } + event_set(ev, sock_fd, EV_READ | EV_PERSIST, &read_cb, (void*)this); + if (event_add(ev, NULL) == -1) { + perror("event_set"); + } + m_sock_fd = sock_fd; + return 0; +} + +UdpGroupLibevent::OnReadDataHandle UdpGroupLibevent::OnReadHandle() { + return this->mOnRead; +} + +void UdpGroupLibevent::SetOnReadHandle(UdpGroupLibevent::OnReadDataHandle p) { + this->mOnRead = p; +} + +void UdpGroupLibevent::SendTo(const char* dat, uint32_t len, std::string ip, int port) { + struct sockaddr_in dest_addr; + memset(&dest_addr, 0, sizeof(dest_addr)); + dest_addr.sin_family = AF_INET; + dest_addr.sin_port = htons(port); + dest_addr.sin_addr.s_addr = inet_addr(ip.c_str()); + int addr_len = sizeof(struct sockaddr); + if (m_sock_fd > 0) { + sendto(m_sock_fd, (const char*)dat, len, 0, (struct sockaddr*)&dest_addr, addr_len); + } +} + +int UdpGroupLibevent::SocketFD() { + return this->mSocketFD; +} + + +UdpGroupLibevent:: +UdpGroupLibevent(std::string ip, uint32_t port) +{ + m_status = STOP; + m_bind_ip = ip; + m_port = port; + if (event_init() == NULL) { + printf("event_init() failed\n"); + } + m_event = new struct event; + if (0 > bind_socket(m_event, ip.c_str(), port)) { + return; + } + + m_thread = new std::thread([this]() { + event_dispatch(); + } + ); + m_status = RUNNING; +} diff --git a/examples/proto_debuger/udp_group_libevent.h b/examples/proto_debuger/udp_group_libevent.h index 85e32fba..590f34ba 100644 --- a/examples/proto_debuger/udp_group_libevent.h +++ b/examples/proto_debuger/udp_group_libevent.h @@ -1,6 +1,4 @@ #pragma once - - #include #ifndef _WIN32_WINNT @@ -28,14 +26,14 @@ class UdpGroupLibevent { public: typedef std::function OnReadDataHandle; UdpGroupLibevent(std::string ip, uint32_t port); - OnReadDataHandle* OnReadHandle(); + OnReadDataHandle OnReadHandle(); typedef enum { RUNNING, STOP, FAIL }STATUS; friend void read_cb(int, short, void*); - void SetOnReadHandle(OnReadDataHandle*); + void SetOnReadHandle(OnReadDataHandle); void SendTo(const char* dat, uint32_t len, std::string ip, int port); int SocketFD(); private: @@ -49,7 +47,7 @@ private: STATUS m_status; // std::thread* m_thread; // 当前线程 intptr_t mSocketFD; // 操作系统原生socket - OnReadDataHandle* mOnRead; + OnReadDataHandle mOnRead; }; diff --git a/examples/proto_debuger/udp_libevent.cpp b/examples/proto_debuger/udp_libevent.cpp index f8f4bbcd..c3155ff1 100644 --- a/examples/proto_debuger/udp_libevent.cpp +++ b/examples/proto_debuger/udp_libevent.cpp @@ -15,7 +15,7 @@ extern "C" { #endif #define MSG_LEN 1024 -void read_cb(evutil_socket_t fd, short event, void* arg) { +static void read_cb(evutil_socket_t fd, short event, void* arg) { UdpDataGramLibevent* parent = (UdpDataGramLibevent*)arg; if (parent == nullptr) return; diff --git a/examples/proto_debuger/udp_libevent.h b/examples/proto_debuger/udp_libevent.h index 0d5de848..a016bb40 100644 --- a/examples/proto_debuger/udp_libevent.h +++ b/examples/proto_debuger/udp_libevent.h @@ -19,7 +19,6 @@ #include #include #include -#include class UdpDataGramLibevent {