Sockeye

An easy-to-use, fast, and robust C++ epoll socket library.

API Reference

sockeye::Socket

Main server class for handling TCP connections.

Constructor

explicit Socket(uint16_t port = 8080, int timeout_ms = 5000)

Constructs a server instance. timeout_ms is the duration of inactivity in milliseconds before a client connection is automatically closed.

Methods

bool start() Initialize the server socket and event system. Returns true on success.

void run() Start the event loop. This is a blocking call that runs until stop() is called.

void stop() Stops the server and causes the run() loop to exit.

bool send(int client_fd, const std::string& data) Sends data to a connected client. This method handles partial sends and ensures all data is written. Returns true on success.

void on_connection(ConnectionHandler handler) Set a callback to be executed when a new client connects.

void on_data(DataHandler handler) Set a callback to be executed when data is received from a client.

void on_disconnect(DisconnectHandler handler) Set a callback to be executed when a client disconnects for any reason (including timeout).

Handler Types

using ConnectionHandler = std::function<void(int client_fd)>;
using DataHandler = std::function<void(int client_fd, const char* data, size_t len)>;
using DisconnectHandler = std::function<void(int client_fd)>;

Examples

Basic Echo Server

This example demonstrates how to echo all received data back to the client. It captures the server object to use the integrated send method.

#include "sockeye.hpp"
#include <iostream>
#include <string>

int main() {
    sockeye::Socket server(8080);

    server.on_connection([](int client_fd) {
        std::cout << "Client connected: " << client_fd << std::endl;
    });

    // Capture server to use its send method
    server.on_data([&server](int client_fd, const char* data, size_t len) {
        // Echo data back to client using the server's send method
        server.send(client_fd, std::string(data, len));
    });

    server.on_disconnect([](int client_fd) {
        std::cout << "Client disconnected: " << client_fd << std::endl;
    });

    if (!server.start()) {
        std::cerr << "Failed to start server" << std::endl;
        return 1;
    }

    server.run();
    return 0;
}

HTTP Server with Keep-Alive

This example shows a simple HTTP server that properly handles keep-alive connections. The library automatically manages client timeouts.

#include "sockeye.hpp"
#include <iostream>
#include <string>
#include <unordered_map>
#include <mutex>

int main() {
    sockeye::Socket server(8080);

    // Buffers for accumulating request data per client
    std::unordered_map<int, std::string> request_buffers;
    std::mutex buffer_mutex;

    server.on_data([&](int client_fd, const char* data, size_t len) {
        std::string request_chunk(data, len);

        std::lock_guard<std::mutex> lock(buffer_mutex);
        request_buffers[client_fd] += request_chunk;

        // Check if we have a full HTTP request
        if (request_buffers[client_fd].find("\r\n\r\n") != std::string::npos) {
            std::string response =
                "HTTP/1.1 200 OK\r\n"
                "Content-Length: 13\r\n"
                "Connection: keep-alive\r\n\r\n"
                "Hello, World!";

            server.send(client_fd, response);

            // Clear buffer for this client for the next request
            request_buffers[client_fd].clear();
        }
    });

    server.on_disconnect([&](int client_fd) {
        std::cout << "Client disconnected: " << client_fd << std::endl;
        std::lock_guard<std::mutex> lock(buffer_mutex);
        request_buffers.erase(client_fd);
    });

    if (!server.start()) {
        std::cerr << "Failed to start server" << std::endl;
        return 1;
    }

    std::cout << "Server listening on port 8080" << std::endl;
    server.run();
    return 0;
}

Graceful Shutdown

This example shows how to catch SIGINT (Ctrl+C) and SIGTERM signals to shut down the server gracefully.

#include "sockeye.hpp"
#include <signal.h>
#include <iostream>

sockeye::Socket* server_ptr = nullptr;

void signal_handler(int signal) {
    if (server_ptr) {
        std::cout << "\nCaught signal " << signal << ", stopping server..." << std::endl;
        server_ptr->stop();
    }
}

int main() {
    sockeye::Socket server(8080);
    server_ptr = &server;

    signal(SIGINT, signal_handler);
    signal(SIGTERM, signal_handler);

    // Set up handlers...
    server.on_connection([](int fd){ /* ... */ });

    if (!server.start()) {
        return 1;
    }

    std::cout << "Server started. Press Ctrl+C to exit." << std::endl;
    server.run();
    std::cout << "Server stopped." << std::endl;

    return 0;
}
Description
Easy-to-use C++ library for utilizing sockets.
Readme 44 KiB
Languages
C++ 100%