19 #include <arpa/inet.h> 21 #include <netinet/in.h> 23 #include <sys/epoll.h> 24 #include <sys/resource.h> 25 #include <sys/socket.h> 26 #include <sys/types.h> 38 typedef bool (T::*
func)(
int fd);
42 listened_port_ = port;
43 msg_handle_ = msg_handle;
46 if (listener_sock_ != -1) {
47 close(listener_sock_);
64 bool setnonblocking(
int sockfd);
65 void MessageHandle(
int fd);
68 T *receiver_ =
nullptr;
69 uint16_t listened_port_ = 0;
70 int listener_sock_ = -1;
71 func msg_handle_ =
nullptr;
77 msg_handle_ = msg_handle;
86 listened_port_ = port;
89 if (setrlimit(RLIMIT_NOFILE, &rt) == -1) {
93 listener_sock_ = socket(AF_INET, SOCK_DGRAM, 0);
94 if (listener_sock_ == -1) {
97 int opt = SO_REUSEADDR;
98 setsockopt(listener_sock_, SOL_SOCKET, SO_REUSEADDR, &opt,
sizeof(opt));
99 setnonblocking(listener_sock_);
101 struct sockaddr_in serv_addr;
102 serv_addr.sin_family = PF_INET;
103 serv_addr.sin_port = htons((uint16_t)listened_port_);
104 serv_addr.sin_addr.s_addr = INADDR_ANY;
105 if (bind(listener_sock_, (
struct sockaddr *)&serv_addr,
106 sizeof(
struct sockaddr)) == -1) {
107 close(listener_sock_);
110 kdpfd_ = epoll_create(MAXEPOLLSIZE);
111 struct epoll_event ev;
112 ev.events = EPOLLIN | EPOLLET;
113 ev.data.fd = listener_sock_;
114 if (epoll_ctl(kdpfd_, EPOLL_CTL_ADD, listener_sock_, &ev) < 0) {
115 close(listener_sock_);
121 template <
typename T>
125 struct epoll_event events[MAXEPOLLSIZE];
127 nfds = epoll_wait(kdpfd_, events, 10000, -1);
133 for (
int i = 0; i < nfds; ++i) {
134 if (events[i].data.fd == listener_sock_) {
137 pthread_attr_init(&attr);
138 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
139 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
141 par->
fd_ = events[i].data.fd;
143 if (pthread_create(&thread, &attr,
145 reinterpret_cast<void *>(par))) {
152 close(listener_sock_);
156 template <
typename T>
158 if (fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFD, 0) | O_NONBLOCK) == -1) {
164 template <
typename T>
174 pthread_exit(
nullptr);
176 listener->MessageHandle(fd);
177 pthread_exit(
nullptr);
180 template <
typename T>
182 if (!receiver_ || !msg_handle_) {
185 (receiver_->*msg_handle_)(fd);
PlanningContext is the runtime context in planning. It is persistent across multiple frames...
Definition: atomic_hash_map.h:25
~UDPListener()
Definition: udp_listener.h:45
constexpr int MAXEPOLLSIZE
Definition: udp_listener.h:33
bool(T::* func)(int fd)
Definition: udp_listener.h:38
bool Initialize(T *receiver, func msg_handle, uint16_t port)
Definition: udp_listener.h:76
UDPListener(T *receiver, uint16_t port, func msg_handle)
Definition: udp_listener.h:40
UDPListener< T > * listener_
Definition: udp_listener.h:60
bool Listen()
Definition: udp_listener.h:122
static void * pthread_handle_message(void *param)
Definition: udp_listener.h:165
int fd_
Definition: udp_listener.h:59
void SetMsgHandle(func msg_handle)
Definition: udp_listener.h:51
Definition: udp_listener.h:36
UDPListener()
Definition: udp_listener.h:39
Definition: udp_listener.h:58