Language: C
Networking / Async
libuv was originally developed as part of Node.js to provide a consistent, event-driven, asynchronous I/O layer across different platforms. It is now used in many other projects that require efficient non-blocking I/O, including networking applications, servers, and frameworks.
libuv is a multi-platform C library that provides asynchronous I/O, event loops, timers, and cross-platform abstractions for networking, filesystems, and concurrency. It is designed to support high-performance, scalable applications.
sudo apt install libuv1-devbrew install libuvDownload precompiled binaries from https://libuv.org/ or build from sourcelibuv allows developers to handle TCP/UDP sockets, files, and timers asynchronously using an event loop. It supports callbacks, handles, streams, and integrates well with C/C++ applications requiring high concurrency.
#include <uv.h>
#include <stdio.h>
int main() {
uv_loop_t *loop = uv_default_loop();
printf("Loop started\n");
uv_run(loop, UV_RUN_DEFAULT);
uv_loop_close(loop);
return 0;
}Initializes the default libuv event loop, runs it (though no events are scheduled), and closes it.
#include <uv.h>
#include <stdio.h>
void timer_cb(uv_timer_t* handle) {
printf("Timer fired!\n");
}
int main() {
uv_loop_t *loop = uv_default_loop();
uv_timer_t timer_req;
uv_timer_init(loop, &timer_req);
uv_timer_start(&timer_req, timer_cb, 1000, 0); // Fire once after 1000ms
uv_run(loop, UV_RUN_DEFAULT);
uv_loop_close(loop);
return 0;
}Sets up a one-time timer that calls a callback after 1 second.
#include <uv.h>
#include <stdio.h>
void on_new_connection(uv_stream_t *server, int status) {
if (status < 0) {
fprintf(stderr, "New connection error: %s\n", uv_strerror(status));
return;
}
printf("New client connected\n");
}
int main() {
uv_loop_t *loop = uv_default_loop();
uv_tcp_t server;
uv_tcp_init(loop, &server);
struct sockaddr_in addr;
uv_ip4_addr("0.0.0.0", 7000, &addr);
uv_tcp_bind(&server, (const struct sockaddr*)&addr, 0);
int r = uv_listen((uv_stream_t*)&server, 128, on_new_connection);
if (r) {
fprintf(stderr, "Listen error: %s\n", uv_strerror(r));
return 1;
}
uv_run(loop, UV_RUN_DEFAULT);
uv_loop_close(loop);
return 0;
}Creates a basic TCP server that listens on port 7000 and prints a message when a client connects.
#include <uv.h>
#include <stdio.h>
#include <stdlib.h>
void read_cb(uv_fs_t* req) {
printf("File content: %s\n", (char*)req->bufs->base);
uv_fs_req_cleanup(req);
}
int main() {
uv_loop_t *loop = uv_default_loop();
uv_fs_t open_req;
uv_fs_open(loop, &open_req, "test.txt", O_RDONLY, 0, NULL);
uv_fs_t read_req;
char *buffer = malloc(1024);
uv_buf_t iov = uv_buf_init(buffer, 1024);
uv_fs_read(loop, &read_req, open_req.result, &iov, 1, 0, read_cb);
uv_run(loop, UV_RUN_DEFAULT);
uv_loop_close(loop);
free(buffer);
return 0;
}Demonstrates asynchronous file reading using libuv.
#include <uv.h>
#include <stdio.h>
void alloc_buffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) {
buf->base = malloc(suggested_size);
buf->len = suggested_size;
}
void on_read(uv_udp_t *req, ssize_t nread, const uv_buf_t *buf, const struct sockaddr *addr, unsigned flags) {
if (nread > 0) printf("Received: %s\n", buf->base);
free(buf->base);
}
int main() {
uv_loop_t *loop = uv_default_loop();
uv_udp_t recv_socket;
uv_udp_init(loop, &recv_socket);
struct sockaddr_in addr;
uv_ip4_addr("0.0.0.0", 7000, &addr);
uv_udp_bind(&recv_socket, (const struct sockaddr*)&addr, 0);
uv_udp_recv_start(&recv_socket, alloc_buffer, on_read);
uv_run(loop, UV_RUN_DEFAULT);
uv_loop_close(loop);
return 0;
}Sets up a UDP server that asynchronously receives messages.
Always initialize and close the event loop properly.
Free memory for buffers and handles to avoid leaks.
Use callbacks to handle events asynchronously.
Leverage libuv timers and async handles for concurrency instead of threads.
Handle errors in callbacks to prevent crashing the loop.