#pragma once #ifdef _WIN32 #include #include #else #include #include #include #endif namespace SocketOptimization { // buffer sizes for different use cases constexpr int WEBSOCKET_BUFFER_SIZE = 32768; // 32KB for WebSocket frames constexpr int HTTP_BUFFER_SIZE = 65536; // 64KB for HTTP responses constexpr int SSL_BUFFER_SIZE = 16384; // 16KB for SSL/TLS data constexpr int SMALL_BUFFER_SIZE = 8192; // 8KB for small reads constexpr int SOCKET_SEND_BUFFER = 256 * 1024; // 256KB send buffer constexpr int SOCKET_RECV_BUFFER = 256 * 1024; // 256KB receive buffer inline bool optimizeSocket(int socket_fd) { if (socket_fd < 0) return false; int nodelay = 1; if (setsockopt(socket_fd, IPPROTO_TCP, TCP_NODELAY, (const char*)&nodelay, sizeof(nodelay)) != 0) { return false; } int send_buffer = SOCKET_SEND_BUFFER; if (setsockopt(socket_fd, SOL_SOCKET, SO_SNDBUF, (const char*)&send_buffer, sizeof(send_buffer)) != 0) { return false; } int recv_buffer = SOCKET_RECV_BUFFER; if (setsockopt(socket_fd, SOL_SOCKET, SO_RCVBUF, (const char*)&recv_buffer, sizeof(recv_buffer)) != 0) { return false; } // disable Nagle int tcp_quickack = 1; #ifndef _WIN32 setsockopt(socket_fd, IPPROTO_TCP, TCP_QUICKACK, (const char*)&tcp_quickack, sizeof(tcp_quickack)); #endif return true; } inline bool optimizeWebSocket(int socket_fd) { if (!optimizeSocket(socket_fd)) return false; int keepalive = 1; if (setsockopt(socket_fd, SOL_SOCKET, SO_KEEPALIVE, (const char*)&keepalive, sizeof(keepalive)) != 0) { return false; } #ifndef _WIN32 // unix keep-alive int keepidle = 30; // start probes after 30 seconds int keepintvl = 5; // probe every 5 seconds int keepcnt = 3; // 3 failed probes before timeout setsockopt(socket_fd, IPPROTO_TCP, TCP_KEEPIDLE, &keepidle, sizeof(keepidle)); setsockopt(socket_fd, IPPROTO_TCP, TCP_KEEPINTVL, &keepintvl, sizeof(keepintvl)); setsockopt(socket_fd, IPPROTO_TCP, TCP_KEEPCNT, &keepcnt, sizeof(keepcnt)); #endif return true; } inline bool optimizeHttp(int socket_fd) { if (!optimizeSocket(socket_fd)) return false; int reuse = 1; if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)) != 0) { return false; } return true; } };