Skip to content

Instantly share code, notes, and snippets.

@trevershick
Last active November 21, 2023 06:54
Show Gist options
  • Save trevershick/080f56b36a0aa81b0658a10fd3b94c22 to your computer and use it in GitHub Desktop.
Save trevershick/080f56b36a0aa81b0658a10fd3b94c22 to your computer and use it in GitHub Desktop.
Simple client and server using libuv and unix domain sockets...
#include <cassert>
#include <iostream>
#include <unistd.h>
#include <uv.h>
void on_connect_cb(uv_connect_t *req, int status);
int main(int argc, char **argv) {
int r;
uv_loop_t *loop = uv_default_loop();
uv_pipe_t pipe;
uv_pipe_init(loop, &pipe, 0);
uv_connect_t *connect = (uv_connect_t *)malloc(sizeof(uv_connect_t));
uv_pipe_connect(connect, &pipe,
"/Users/trever.shick/workspaces/primary/prometheus/scripts/"
"taniumtsdb.sock",
on_connect_cb);
r = uv_run(loop, UV_RUN_DEFAULT);
std::cout << "Done, uv_run returned " << r << std::endl;
return 0;
}
void alloc_buffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) {
buf->base = (char *)malloc(3);
buf->len = 3;
}
void echo_read(uv_stream_t *client, ssize_t nread, const uv_buf_t *buf) {
std::cerr << "nread is " << nread << ", buf is " << buf->len
<< "last char is " << (int)buf->base[buf->len - 1] << std::endl;
if (nread == buf->len) {
std::cout << "Client's buffer is full" << std::endl;
}
if (buf->base[nread - 1] == 0) {
std::cout << "Client has received NULL BYTE, done." << std::endl;
uv_close((uv_handle_t *)client, NULL);
return;
}
if ((nread >= 0 && nread < buf->len) || nread == UV_EOF ||
buf->base[nread - 1] == 0) {
std::cout << "Client has received chars, done." << std::endl;
std::cerr << "Close connection from client side" << std::endl;
uv_close((uv_handle_t *)client, NULL);
return;
}
if (nread < 0) {
if (nread != UV_EOF)
fprintf(stderr, "Read error %s\n", uv_err_name(nread));
else
std::cerr << "Received EOF" << std::endl;
uv_close((uv_handle_t *)client, NULL);
}
}
void after_write(uv_write_t *req, int status) {
free(req);
// ok now read the results
uv_read_start((uv_stream_t *)req->handle, alloc_buffer, echo_read);
}
void on_connect_cb(uv_connect_t *req, int status) {
assert(status == 0);
int r;
uv_write_t *wreq = (uv_write_t *)malloc(sizeof(uv_write_t));
const char *request = "{ \"action\":\"labels\" }";
const uv_buf_t b = uv_buf_init(strdup(request), strlen(request) + 1);
uv_write((uv_write_t *)wreq, req->handle, &b, 1, after_write);
}
set(CMAKE_BUILD_TYPE Debug)
cmake_minimum_required(VERSION 2.8.12)
project(libuv1)
add_definitions("-std=c++11")
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()
add_executable(server server.cpp)
target_link_libraries(server ${CONAN_LIBS})
add_executable(client client.cpp)
target_link_libraries(client ${CONAN_LIBS})
[requires]
libuv/1.24.0@bincrafters/stable
[generators]
cmake
#include <cassert>
#include <iostream>
#include <unistd.h>
#include <uv.h>
void on_connect_cb(uv_stream_t *, int);
int main(int argc, char **argv) {
int r;
uv_loop_t *loop = uv_default_loop();
uv_pipe_t pipe;
// uv_loop_init(&loop);
uv_pipe_init(loop, &pipe, 0);
unlink("/tmp/test.sock");
uv_pipe_bind(&pipe, "/tmp/test.sock");
uv_listen((uv_stream_t *)&pipe, 0, on_connect_cb);
r = uv_run(loop, UV_RUN_DEFAULT);
std::cout << "Done, uv_run returned " << r << std::endl;
return 0;
}
void alloc_buffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) {
buf->base = (char *)malloc(3);
buf->len = 3;
}
void echo_write(uv_write_t *req, int status) { free(req); }
void echo_read(uv_stream_t *client, ssize_t nread, const uv_buf_t *buf) {
std::cerr << "nread is " << nread << ", buf is " << buf->len
<< " last char is " << (int)buf->base[buf->len - 1] << std::endl;
if (nread == buf->len) {
std::cerr << "received " << std::string(buf->base, buf->len) << std::endl;
std::cerr << "Server buffer full, wait for more data" << std::endl;
}
if ((nread >= 0 && nread < buf->len) || nread == UV_EOF) {
std::cerr << "received " << std::string(buf->base, buf->len) << std::endl;
std::cerr << "write 'gotem' to the client" << std::endl;
uv_write_t *req = (uv_write_t *)malloc(sizeof(uv_write_t));
const uv_buf_t b = uv_buf_init(strdup("gotem"), 5);
uv_write((uv_write_t *)req, client, &b, 1, echo_write);
std::cerr << "Close Connection" << std::endl;
uv_close((uv_handle_t *)client, NULL);
return;
}
if (nread < 0) {
if (nread != UV_EOF)
fprintf(stderr, "Read error %s\n", uv_err_name(nread));
else
std::cerr << "Received EOF" << std::endl;
uv_close((uv_handle_t *)client, NULL);
}
}
void on_connect_cb(uv_stream_t *stream, int status) {
assert(status == 0);
int r;
uv_pipe_t *client = (uv_pipe_t *)malloc(sizeof(uv_pipe_t));
uv_pipe_init(stream->loop, client, 0);
r = uv_accept(stream, (uv_stream_t *)client);
assert(r == 0);
uv_read_start((uv_stream_t *)client, alloc_buffer, echo_read);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment