-
-
Save zhzhxtrrk/6161784 to your computer and use it in GitHub Desktop.
libuv example
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> | |
static uv_buf_t | |
alloc_buffer(uv_handle_t *handle, size_t size) | |
{ | |
return uv_buf_init(malloc(size), size); | |
} | |
static uv_buf_t | |
copy_buffer(uv_buf_t buf, size_t size) | |
{ | |
uv_buf_t dest = uv_buf_init(malloc(size), size); | |
memcpy(dest.base, buf.base, size); | |
return dest; | |
} | |
static void | |
free_buffer(uv_buf_t buf) | |
{ | |
if (buf.base) { | |
free(buf.base); | |
} | |
} | |
typedef struct write_context_s | |
{ | |
uv_buf_t buf; | |
} write_context_t; | |
static void | |
on_close(uv_handle_t *client) | |
{ | |
printf("Closed, bye!\n"); | |
free(client); | |
} | |
static void | |
on_write(uv_write_t *write, int status) | |
{ | |
write_context_t *context; | |
if (status) { | |
printf("Write error\n"); | |
if (!uv_is_closing((uv_handle_t*)write->handle)) | |
uv_close((uv_handle_t*)write->handle, on_close); | |
} | |
context = (write_context_t*) write->data; | |
free_buffer(context->buf); | |
free(context); | |
free(write); | |
} | |
static void | |
on_read(uv_stream_t *client, ssize_t nread, uv_buf_t buf) | |
{ | |
if (nread == -1) { | |
if (uv_last_error(client->loop).code == UV_EOF) { | |
printf("Client closed connection\n"); | |
} else { | |
printf("Read error\n"); | |
} | |
if (!uv_is_closing((uv_handle_t*)client)) | |
uv_close((uv_handle_t*)client, on_close); | |
} else { | |
uv_write_t *write; | |
write_context_t *write_context; | |
printf("data read %zd bytes, buffer length %zd bytes.\n", | |
nread, buf.len); | |
write = malloc(sizeof(uv_write_t)); | |
write_context = malloc(sizeof(write_context_t)); | |
write_context->buf = copy_buffer(buf, nread); | |
write->data = write_context; | |
uv_write(write, client, &write_context->buf, 1, on_write); | |
} | |
free_buffer(buf); | |
} | |
static void | |
on_connect(uv_stream_t *server, int status) | |
{ | |
uv_tcp_t *client; | |
if (status) { | |
printf("accept connection error!\n"); | |
} else { | |
client = malloc(sizeof(uv_tcp_t)); | |
uv_tcp_init(server->loop, client); | |
if (uv_accept(server, (uv_stream_t *)client)) { | |
uv_close((uv_handle_t*)client, NULL); | |
free(client); | |
} else { | |
uv_read_start((uv_stream_t*)client, alloc_buffer, on_read); | |
} | |
} | |
} | |
int | |
main(int argc, char** argv) | |
{ | |
uv_loop_t *loop; | |
uv_tcp_t *server; | |
struct sockaddr_in addr; | |
loop = uv_default_loop(); | |
server = malloc(sizeof(uv_tcp_t)); | |
uv_tcp_init(loop, server); | |
addr = uv_ip4_addr("0.0.0.0", 3000); | |
uv_tcp_bind(server, addr); | |
if (uv_listen((uv_stream_t*)server, 128, on_connect)) { | |
printf("Error!\n"); | |
return 1; | |
} | |
uv_run(loop, UV_RUN_DEFAULT); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment