MoonNet guide_en
MoonNet Guide
Overview
MoonNet is a lightweight, high-performance, event-driven network library based on C++. It aims to simplify the development of network applications, supporting both TCP and UDP protocols. It provides an efficient event loop mechanism for handling asynchronous I/O operations. With its modular design, MoonNet offers flexible interfaces that allow developers to quickly build high-performance network services.
Table of Contents
- Module Overview
- Classes and Interfaces
- Usage Examples
- Error Handling
- Frequently Asked Questions (FAQs)
- Conclusion
Module Overview
The core modules of MoonNet include:
- Event Loop (
eventloop
): Manages the registration, deletion, and distribution of events, implementing the core Reactor model. - Event (
event
): Represents an event on a file descriptor, encapsulating event callbacks and trigger mechanisms. - Buffer (
buffer
): Handles data buffering for non-blocking I/O, implementing data caching and processing. - Buffered Event (
bfevent
): A buffer-based event handling class, encapsulating read/write buffers and callbacks. - UDP Event (
udpevent
): Handles the sending and receiving of UDP packets. - Timer Event (
timerevent
): Provides timer functionality, supporting one-time and periodic timers. - Signal Event (
signalevent
): Handles UNIX signals, integrating signal events into the event loop. - Acceptor (
acceptor
): Listens on TCP ports and accepts new connections. - Server (
server
): Encapsulates TCP and UDP server functionalities, managing connections, events, and thread pools.
Note: The commented-out section labeled
/** v1.0.0 **/
contains deprecated or previous versions of event handling functions. These have been superseded by the generalized functions to provide a unified approach to event management.
Classes and Interfaces
base_event
Description:
base_event
is the base class for all event types, defining the basic interfaces and behaviors of an event.
Interface:
1 |
|
Function Descriptions:
virtual eventloop* getloop() const = 0;
Retrieves the associated event loop object.virtual void close() = 0;
Closes the event and releases related resources.virtual void disable_cb() = 0;
Disables the event’s callback functions to prevent it from being triggered again.virtual void enable_listen() = 0;
Enables event listening.
virtual void del_listen() = 0;
Removes the event listening.
virtual void update_ep() = 0;
Updates the event’s status in epoll.
event
Description:
The event
class represents an event on a file descriptor, encapsulating the event type, callback functions, and trigger mechanisms.
Interface:
1 |
|
Function Descriptions:
event(eventloop* base, int fd, uint32_t events);
Constructor that initializes the event object.~event();
Destructor that releases resources.int getfd() const;
Gets the file descriptor associated with the event.uint32_t getevents() const;
Gets the event types being listened to.eventloop* getloop() const override;
Retrieves the associated event loop object.void setcb(const Callback& rcb, const Callback& wcb, const Callback& ecb);
Sets the read, write, and error event callback functions.void setrcb(const Callback& rcb);
Sets the read event callback function.void setwcb(const Callback& wcb);
Sets the write event callback function.void setecb(const Callback& ecb);
Sets the error event callback function.void setrevents(const uint32_t revents);
Sets the triggered event types.void enable_events(uint32_t op);
Enables specific event types.void disable_events(uint32_t op);
Disables specific event types.void update_ep() override;
Updates the event’s status in epoll.void handle_cb();
Handles the event by calling the appropriate callback functions.bool readable();
Checks if the event is readable.bool writeable();
Checks if the event is writable.void enable_read();
Enables read event listening.void disable_read();
Disables read event listening.void enable_write();
Enables write event listening.void disable_write();
Disables write event listening.void enable_ET();
Enables edge-triggered mode.void disable_ET();
Disables edge-triggered mode.void reset_events();
Resets the event types.void del_listen() override;
Removes the event listening.void enable_listen() override;
Enables event listening.void disable_cb() override;
Disables the event’s callback functions.void close() override;
Closes the event.
eventloop
Description:
The eventloop
class is the core of the event loop, implementing the Reactor model and managing the registration, deletion, and distribution of all events.
Interface:
1 |
|
Function Descriptions:
eventloop(loopthread* base = nullptr, int timeout = -1);
Constructor that initializes the event loop object.~eventloop();
Destructor that releases resources.loopthread* getbaseloop();
Gets the associated thread object.int getefd() const;
Gets the epoll file descriptor.int getevfd() const;
Gets the event notification file descriptor.int getload() const;
Gets the current load (number of active events) of the event loop.void add_event(event* event);
Adds an event to be listened to by epoll.void del_event(event* event);
Removes an event from epoll.void mod_event(event* event);
Modifies the event’s listening types.void loop();
Starts the event loop and handles events.void loopbreak();
Stops the event loop.void getallev(std::list<event*>& list);
Retrieves all events in the list.void create_eventfd();
Creates an event notification file descriptor.void read_eventfd();
Reads from the event notification file descriptor to handle loop termination signals.void write_eventfd();
Writes to the event notification file descriptor to notify the event loop to terminate.void add_pending_del(base_event* ev);
Adds an event to the pending deletion queue.
loopthread
Description:
The loopthread
class encapsulates an event loop thread used to run an eventloop
.
Interface:
1 |
|
Function Descriptions:
loopthread(int timeout = -1);
Constructor that initializes the thread and creates the event loop.~loopthread();
Destructor that terminates the thread and releases resources.eventloop* getloop();
Gets the event loop object.void _init_();
Internal function that initializes the event loop and starts looping.
looptpool
Description:
The looptpool
class manages a group of event loop threads (loopthread
), implementing thread pool functionality and providing static/dynamic load balancing.
Interface:
1 |
|
Function Descriptions:
looptpool(eventloop* base, bool dispath = false);
Constructor that initializes the thread pool and specifies whether to enable dynamic load balancing.~looptpool();
Destructor that releases resources.void create_pool(int timeout = -1);
Creates the thread pool with the default number of threads.void create_pool(int n, int timeout);
Creates the thread pool with a specified number of threads.void create_pool_noadjust(int n, int timeout);
Creates the thread pool without dynamic adjustment.eventloop* ev_dispatch();
Dispatches events to event loops in the thread pool.void delloop_dispatch();
Deletes the event loop with the maximum load and redistributes its events.void addloop();
Adds a new event loop thread.void adjust_task();
Management thread task for dynamically adjusting the number of threads.int getscale();
Gets the average load scale.void enable_adjust();
Enables dynamic load balancing.void stop();
Stops the thread pool and terminates all event loops.
Threadpool
Description:
The Threadpool
class implements a general-purpose thread pool for executing arbitrary task functions.
Interface:
1 |
|
Function Descriptions:
Threadpool(int num);
Constructor that initializes the thread pool with a specified minimum number of threads.~Threadpool();
Destructor that shuts down the thread pool.void add_task(_Fn&& fn, _Args&&... args);
Adds a task to the thread pool, specifying the task function and its arguments.void init();
Initializes the thread pool, creating worker and management threads.void t_shutdown();
Shuts down the thread pool, terminating all threads.void t_task();
Entry function for worker threads to execute tasks.void adjust_task();
Entry function for the management thread to dynamically adjust the number of threads.
buffer
Description:
The buffer
class implements an auto-expanding buffer for handling data caching and operations in non-blocking I/O.
Interface:
1 |
|
Function Descriptions:
buffer();
Constructor that initializes the buffer.~buffer();
Destructor that releases resources.void append(const char* data, size_t len);
Appends data to the buffer.size_t remove(char* data, size_t len);
Reads data from the buffer into a specified memory location.std::string remove(size_t len);
Reads data from the buffer and returns it as a string.void retrieve(size_t len);
Moves the read pointer forward, marking data as read without copying.size_t readbytes() const;
Gets the number of bytes available for reading.size_t writebytes() const;
Gets the number of bytes available for writing.const char* peek() const;
Gets a pointer to the data at the current read position.void reset();
Resets the buffer, clearing all data.ssize_t readiov(int fd, int& errnum);
Reads data from a file descriptor into the buffer using scatter/gather I/O.
bfevent
Description:
The bfevent
class is a buffer-based event handling class, encapsulating read/write buffers and callbacks, handling data transmission for TCP connections.
Interface:
1 |
|
Function Descriptions:
bfevent(eventloop* base, int fd, uint32_t events);
Constructor that initializes the buffered event object.~bfevent();
Destructor that closes the event and releases resources.int getfd() const;
Gets the file descriptor.eventloop* getloop() const override;
Retrieves the associated event loop.buffer* getinbuff();
Gets the input buffer.buffer* getoutbuff();
Gets the output buffer.bool writeable() const;
Checks if the event is writable.void setcb(const RCallback& rcb, const Callback& wcb, const Callback& ecb);
Sets the read, write, and error event callback functions.void update_ep() override;
Updates the event listening.void del_listen() override;
Cancels event listening.void enable_listen() override;
Enables event listening.void sendout(const char* data, size_t len);
Sends data.void sendout(const std::string& data);
Sends data.size_t receive(char* data, size_t len);
Receives data into specified memory.std::string receive(size_t len);
Receives a specified length of data.std::string receive();
Receives all available data.void enable_events(uint32_t op);
Enables specific events.void disable_events(uint32_t op);
Disables specific events.void enable_read();
Enables read events.void disable_read();
Disables read events.void enable_write();
Enables write events.void disable_write();
Disables write events.void enable_ET();
Enables edge-triggered mode.void disable_ET();
Disables edge-triggered mode.void disable_cb() override;
Disables callback functions.void close() override;
Closes the event.
udpevent
Description:
The udpevent
class handles the transmission and reception of UDP protocol data, supporting non-blocking UDP communication.
Interface:
1 |
|
Function Description:
udpevent(eventloop* base, int port);
Constructor: Initializes the UDP event object with the specified event loop and port number.~udpevent();
Destructor: Closes the event and releases resources.buffer* getinbuff();
Get Input Buffer: Retrieves the input buffer.eventloop* getloop() const override;
Get Event Loop: Retrieves the associated event loop.void setcb(const RCallback& rcb, const Callback& ecb);
Set Callbacks: Sets the receive and error event callback functions.void setrcb(const RCallback& rcb);
Set Receive Callback: Sets the receive event callback function.void setecb(const Callback& ecb);
Set Error Callback: Sets the error event callback function.void init_sock(int port);
Initialize Socket: Initializes the UDP socket.void enable_listen() override;
Enable Listening: Starts listening for UDP packets.void del_listen() override;
Disable Listening: Stops listening for UDP packets.void update_ep() override;
Update Event: Updates the listening event within the event loop.size_t receive(char* data, size_t len);
Receive Data: Receives data into the specified memory buffer.std::string receive(size_t len);
Receive Specified Length Data: Receives a specified length of data from the buffer.std::string receive();
Receive All Readable Data: Receives all readable data from the buffer.void send_to(const std::string& data, const sockaddr_in& addr);
Send Data To: Sends data to the specified address.void enable_read();
Enable Read Event: Enables the read event for the UDP socket.void disable_read();
Disable Read Event: Disables the read event for the UDP socket.void enable_ET();
Enable Edge Triggered: Enables edge-triggered behavior for the UDP socket.void disable_ET();
Disable Edge Triggered: Disables edge-triggered behavior for the UDP socket.void disable_cb() override;
Disable Callback: Disables the assigned callback functions.RCallback getrcb();
Get Receive Callback: Retrieves the currently assigned receive callback function.Callback getecb();
Get Error Callback: Retrieves the currently assigned error callback function.void close() override;
Close Event: Closes the UDP event and cleans up resources.void handle_receive();
Handle Receive Event: Processes incoming data when a receive event is triggered.
timerevent
Description:
The timerevent
class implements timer functionalities, supporting both one-time and periodic timers for executing tasks at regular intervals.
Interface:
1 |
|
Function Description:
timerevent(eventloop* loop, int timeout_ms, bool periodic);
Constructor: Initializes the timer event with the specified event loop, timeout in milliseconds, and a flag indicating whether the timer is periodic.~timerevent();
Destructor: Closes the timer and releases associated resources.int getfd() const;
Get File Descriptor: Retrieves the file descriptor associated with the timer.eventloop* getloop() const override;
Get Event Loop: Retrieves the associated event loop.void setcb(const Callback& cb);
Set Callback: Assigns a callback function to be executed when the timer expires.void enable_listen() override;
Enable Listening: Starts the timer, enabling it to trigger events based on the specified timeout.void del_listen() override;
Disable Listening: Stops the timer from triggering further events.void update_ep() override;
Update Event: Updates the event’s state within the event loop, typically used after modifying timer settings.void close() override;
Close Event: Closes the timer event and cleans up resources.void disable_cb() override;
Disable Callback: Disables the assigned callback function, preventing it from being executed when the timer expires.Callback getcb();
Get Callback: Retrieves the currently assigned callback function.void _init_();
Initialize Timer: Internal method to initialize timer settings and configurations.void handle_timeout();
Handle Timeout: Internal method invoked when the timer expires, executing the assigned callback function.
signalevent
Description:
The signalevent
class handles UNIX signals by integrating signal events into the event loop using a pipe mechanism.
Interface:
1 |
|
Function Description:
signalevent(eventloop* base);
Constructor: Initializes the signal event object with the given event loop.~signalevent();
Destructor: Closes the event and releases resources.eventloop* getloop() const override;
Get Event Loop: Retrieves the associated event loop.void add_signal(int signo);
Add Single Signal: Adds a listener for a single signal.void add_signal(const std::vector<int>& signals);
Add Multiple Signals: Adds listeners for multiple signals.void setcb(const Callback& cb);
Set Callback: Assigns a callback function to handle signals.void enable_listen() override;
Enable Listening: Starts listening for the configured signals.void del_listen() override;
Disable Listening: Stops listening for signals.void update_ep() override;
Update Event: Updates the event’s state within the event loop.void disable_cb() override;
Disable Callback: Disables the assigned callback function.void close() override;
Close Event: Closes the signal event and cleans up resources.Callback getcb();
Get Callback: Retrieves the currently assigned callback function.static void handle_signal(int signo);
Handle Signal (Static): Static method to handle incoming signals and forward them to the appropriate instance.void handle_read();
Handle Read: Processes the signal read from the pipe.
acceptor
Description:
The acceptor
class is responsible for listening on a specified port, accepting new TCP connections, and handing them off to a callback function.
Interface:
1 |
|
Function Descriptions:
acceptor(int port, eventloop* base);
Constructor that initializes the acceptor object.~acceptor();
Destructor that stops listening and releases resources.void listen();
Starts listening.void stop();
Stops listening.void init_sock(int port);
Initializes the listening socket.void setcb(const Callback& accept_cb);
Sets the callback function for new connections.void handle_accept();
Handles new connection events.
server
Description:
The server
class encapsulates TCP and UDP server functionalities, managing connections, events, and thread pools.
Interface:
1 |
|
Function Description:
server(int port = -1);
Constructor: Initializes the server object.~server();
Destructor: Shuts down the server and releases resources.void start();
Start the server: Begins the event loop.void stop();
Stop the server: Terminates the event loop.void init_pool(int timeout = -1);
Initialize the thread pool: Sets up the thread pool with an optional timeout.void enable_tcp(int port);
Enable TCP service: Activates TCP functionality on the specified port.void enable_tcp_accept();
Enable TCP connection listening: Starts listening for incoming TCP connections.void disable_tcp_accept();
Disable TCP connection listening: Stops listening for incoming TCP connections.eventloop* getloop();
Get the main event loop: Retrieves the primary event loop instance.eventloop* dispatch();
Dispatch events: Distributes events to the thread pool.void set_tcpcb(const RCallback& rcb, const Callback& wcb, const Callback& ecb);
Set TCP connection callbacks: Assigns callback functions for read, write, and error events on TCP connections.void addev(base_event *ev);
Add a general event: Adds a generic event (can pass any event type).void delev(base_event *ev);
Delete a general event: Removes a generic event (can pass any event type).void modev(base_event *ev);
Modify a general event: Modifies a generic event (can pass any event type).udpevent* add_udpev(int port, const UCallback& rcb, const Callback& ecb);
Add and initialize a UDP event: Adds audpevent
and initializes it. It is recommended to use this function to add audpevent
, as it will automatically clean up in case of errors.signalevent* add_sev(int signo, const SCallback& cb);
Add and initialize a signal event: Adds asignalevent
for a specific signal number and assigns a callback function.signalevent* add_sev(const std::vector<int>& signals, const SCallback& cb);
Add and initialize multiple signal events: Addssignalevent
instances for a list of signal numbers and assigns a callback function.timerevent* add_timeev(int timeout_ms, bool periodic, const Callback& cb);
Add and initialize a timer event: Adds atimerevent
with a specified timeout in milliseconds, a flag indicating if it is periodic, and assigns a callback function.
wrap
Description:
The wrap
module encapsulates cross-platform socket operation functions, providing a unified interface for both Windows and Unix systems.
Interface:
1 |
|
Function Descriptions:
void settcpnodelay(int fd);
Sets the socket to no-delay mode (TCP_NODELAY
).void setreuse(int fd);
Sets the socket’s address and port to be reusable.void setnonblock(int fd);
Sets the socket to non-blocking mode.void perr_exit(const char* s);
Prints an error message and exits the program.int Accept(int fd, struct sockaddr* sa, socklen_t* salenptr);
Accepts a new connection.int Bind(int fd, const struct sockaddr* sa, socklen_t salen);
Binds the socket to a specified address and port.int Connect(int fd, const struct sockaddr* sa, socklen_t salen);
Connects to a specified address and port.int Listen(int fd, int backlog);
Starts listening on the socket.int Socket(int family, int type, int protocol);
Creates a new socket.ssize_t Read(int fd, void* ptr, size_t nbytes);
Reads data from the socket.ssize_t Write(int fd, const void* ptr, size_t nbytes);
Writes data to the socket.int Close(int fd);
Closes the socket.ssize_t Readn(int fd, void* vptr, size_t n);
Reads a specified number of bytes from the socket.ssize_t Writen(int fd, const void* vptr, size_t n);
Writes a specified number of bytes to the socket.ssize_t Readline(int fd, void* vptr, size_t maxlen);
Reads a line of data from the socket.
Usage Examples
The following examples demonstrate how to use the MoonNet network library to build TCP and UDP servers, as well as how to use timer and signal handling functionalities.
TCP Server Example
Description:
Creates a simple TCP server that listens on a specified port, accepts client connections, and echoes back received data.
Code Example:
1 |
|
Explanation:
Create Server Instance:
1
moon::server tcp_server(8080);
Creates a
server
object that listens on TCP port8080
.Set Callback Functions:
1
tcp_server.set_tcpcb(on_read, on_write, on_event);
Sets the buffered event’s read, write, and error callback functions.
Initialize Thread Pool:
1
tcp_server.init_pool();
Initializes the thread pool to improve the server’s concurrency handling capabilities.
Start Server:
1
tcp_server.start();
Starts the server, begins the event loop, and listens for and handles connections.
UDP Server Example
Description:
Creates a simple UDP server that listens on a specified port, receives data packets, and replies to clients.
Code Example:
1 |
|
Explanation:
Create Server Instance:
1
moon::server udp_server(-1);
Creates a
server
object without enabling TCP service.Add UDP Event:
1
udp_server.add_udpev(5005, on_udp_receive, nullptr);
Adds a UDP event that listens on port
5005
and sets the receive callback function.Start Server:
1
udp_server.start();
Starts the server, begins the event loop, and listens for and handles UDP packets.
Timer Example
Description:
Uses a timer to periodically execute a task, such as printing a message every second.
Code Example:
1 |
|
Explanation:
Create Server Instance:
1
moon::server timer_server(-1);
Creates a
server
object without enabling TCP service.Add Timer Event:
1
timer_server.add_timeev(1000, true, on_timer);
Adds a timer event with a timeout of
1000
milliseconds (1 second). Thetrue
parameter indicates that the timer is periodic.Start Server:
1
timer_server.start();
Starts the server, begins the event loop, and the timer starts working.
Signal Handling Example
Description:
Uses the signal event handling class to listen for and respond to specific UNIX signals, such as SIGINT
(Ctrl+C).
Code Example:
1 |
|
Explanation:
Create Server Instance:
1
moon::server signal_server(-1);
Creates a
server
object without enabling TCP service.Add Signal Event:
1
2std::vector<int> signals = {SIGINT, SIGTERM};
signal_server.add_sev(signals, on_signal);Adds a signal event to listen for
SIGINT
andSIGTERM
signals and sets the callback function.Start Server:
1
signal_server.start();
Starts the server, begins the event loop, and the signal handling starts working.
Error Handling
MoonNet uses standard POSIX error handling mechanisms. When an error occurs, the library calls the perr_exit
function to print an error message and terminate the program. Users can customize error handling logic as needed, such as modifying callback functions to handle specific error situations.
Example:
In wrap.cpp
, the perr_exit
function:
1 |
|
Custom Error Handling:
If you want to avoid directly exiting the program when an error occurs, you can modify the perr_exit
function or add error handling logic in the callback functions.
Example:
Handling errors in the callback function instead of exiting:
1 |
|
Frequently Asked Questions (FAQs)
1. How do I enable both TCP and UDP services simultaneously?
Answer:
Create a server
instance, enable TCP service, and add UDP events.
Example:
1 |
|
2. How do I gracefully shut down the server?
Answer:
Call the stop()
method to interrupt the event loop and ensure all resources are properly released.
Example:
1 |
|
3. How do I handle data race issues in multithreading?
Answer:
MoonNet minimizes data race issues through its design of thread pools and event loops. Each event loop runs in an independent thread. When processing data in callback functions, users should ensure thread-safe access to shared resources, using synchronization mechanisms like mutexes (std::mutex
).
Example:
1 |
|
Conclusion
MoonNet provides an efficient and easy-to-use network programming framework suitable for building various types of network applications. With its modular design and flexible interfaces, developers can quickly implement high-performance network services. We hope this documentation helps you better understand and use the MoonNet network library.
If you have any questions or suggestions, feel free to contact the author or submit feedback.