Event Driven Programming: In a event driven programming, a user register a set of events(in which he is interested in ) and callbacks to those events. In our case, libuv is responsible for gathering events from the operating system and monitoring them. Some of the examples of event loop are file is ready for writing, timer timed out, socket has data ready to be read, etc. When the registered events occur the callbacks invoked by the user are invoked.
Libuv uses asynchronous, non-blocking style to deal with events and callback. Not getting into the details or advantages of it, you can find plenty of articles and blog on it.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <uv.h> | |
int main() { | |
uv_loop_t *loop; | |
loop = malloc(sizeof(uv_loop_t)); | |
//Initializes the given uv_loop_t structure | |
uv_loop_init(loop); | |
//runs the event loop | |
uv_run(loop, UV_RUN_DEFAULT); | |
uv_loop_close(loop); | |
free(loop); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <uv.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#define MAX_DATA_SIZE 512 | |
void sigint_handler(uv_signal_t *handle, int signum) { | |
printf("sigint_handler() : recvd CTRL+C shutting down\n"); | |
uv_stop(uv_default_loop()); //stops the event loop | |
} | |
void alloc_recv_buf(uv_handle_t *receive_handle, size_t suggested_size, | |
uv_buf_t *buf) { | |
buf->base = (char*) malloc(sizeof(char)*MAX_DATA_SIZE); | |
buf->len = MAX_DATA_SIZE; | |
} | |
void udp_receive_callback(uv_udp_t *handle, ssize_t nread, const uv_buf_t *buf, | |
struct sockaddr *addr, unsigned flags) { | |
printf("udp_receive_callback() : start \n"); | |
char string[MAX_DATA_SIZE]; | |
strncpy(string, buf->base, nread); | |
string[nread]='\0'; | |
printf("Recvd : size:%d\tdata:%s\n", nread, string); | |
free(buf->base); | |
printf("udp_receive_callback() : end\n"); | |
} | |
int main(int argc, char** argv){ | |
uv_signal_t sigint; //signal handle type | |
uv_udp_t udp_handle; //UDP handle type | |
struct sockaddr_in server_addr; | |
uv_loop_t *loop; //loop data type | |
loop = uv_default_loop(); //Returns the initialized default loop | |
uv_signal_init(loop, &sigint);//Initialize the handle | |
//Start the handle with the given callback, watching for the given signal. | |
uv_signal_start(&sigint, sigint_handler, SIGINT); | |
//Convert a string containing an IPv4 addresses to a binary structure | |
uv_ip4_addr("0.0.0.0", 9000, &server_addr); | |
printf("main() : uv_sgnal_init() & uv_signal_start() : OK\n"); | |
uv_udp_init(loop, &udp_handle); //Initialize a new UDP handle | |
//Bind the UDP handle to an IP address and port. | |
uv_udp_bind(&udp_handle, (struct sockaddr *)&server_addr, 0); | |
printf("main() : uv_udp_init() & uv_udp_bind() : OK\n"); | |
//Prepare for receiving data. | |
uv_udp_recv_start(&udp_handle, alloc_recv_buf, udp_receive_callback); | |
//runs the event loop. | |
uv_run(loop, UV_RUN_DEFAULT); | |
return 0; | |
} |
Hope you find this useful.