High-performance TCP mock server

If you need a high-performance TCP mock server that:

  1. Handles plain TCP connections (not HTTP).
  2. Reads incoming requests where the first 8 characters represent the length of the request.
  3. Efficiently handles thousands of connections with minimal overhead.
  4. Uses epoll for high TPS (Linux).

Optimized Approach

  • epoll for Non-blocking I/O: Handles multiple clients efficiently.
  • read() loop: Ensures full request reception.
  • send() for fixed response: No complex logic, just echoing back.
  • No fork or threads: Single-threaded, event-driven for maximum TPS.

High-Performance Plain TCP Mock Server in C

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/epoll.h>
#include <arpa/inet.h>

#define PORT 8080
#define MAX_EVENTS 1024
#define BUFFER_SIZE 8192
#define RESPONSE "MOCK_RESPONSE"

void set_nonblocking(int sock) {
    int flags = fcntl(sock, F_GETFL, 0);
    fcntl(sock, F_SETFL, flags | O_NONBLOCK);
}

int parse_length(const char *buffer) {
    char len_str[9] = {0}; // 8 characters + null terminator
    strncpy(len_str, buffer, 8);
    return atoi(len_str);
}

int main() {
    int server_fd, client_fd, epoll_fd;
    struct sockaddr_in server_addr, client_addr;
    struct epoll_event event, events[MAX_EVENTS];
    socklen_t client_len = sizeof(client_addr);
    char buffer[BUFFER_SIZE];

    // Create TCP socket
    server_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (server_fd < 0) {
        perror("Socket failed");
        exit(EXIT_FAILURE);
    }

    // Allow immediate reuse of the port
    int opt = 1;
    setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

    // Bind to port
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = INADDR_ANY;
    server_addr.sin_port = htons(PORT);
    bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr));

    // Start listening
    listen(server_fd, SOMAXCONN);
    set_nonblocking(server_fd);

    // Setup epoll
    epoll_fd = epoll_create1(0);
    event.events = EPOLLIN;
    event.data.fd = server_fd;
    epoll_ctl(epoll_fd, EPOLL_CTL_ADD, server_fd, &event);

    printf("Mock TCP server listening on port %d\n", PORT);

    while (1) {
        int num_events = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
        for (int i = 0; i < num_events; i++) {
            if (events[i].data.fd == server_fd) {
                // Accept new connections
                while ((client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &client_len)) > 0) {
                    set_nonblocking(client_fd);
                    event.events = EPOLLIN | EPOLLET;
                    event.data.fd = client_fd;
                    epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client_fd, &event);
                }
            } else {
                // Handle client request
                client_fd = events[i].data.fd;
                int total_read = 0, request_length = -1;
                
                while (1) {
                    int bytes_read = read(client_fd, buffer + total_read, BUFFER_SIZE - total_read);
                    if (bytes_read <= 0) break; // No more data to read
                    
                    total_read += bytes_read;
                    
                    if (total_read >= 8 && request_length == -1) {
                        // Extract length from first 8 characters
                        request_length = parse_length(buffer);
                    }

                    // Ensure the full request is read
                    if (request_length != -1 && total_read >= request_length) {
                        send(client_fd, RESPONSE, sizeof(RESPONSE) - 1, 0);
                        close(client_fd); // Close connection after responding
                        break;
                    }
                }
            }
        }
    }

    close(server_fd);
    return 0;
}

How It Works

  1. TCP Socket Setup:

    • Creates a non-blocking server socket (server_fd).
    • Uses SO_REUSEADDR for fast restarts.
    • Uses epoll to efficiently handle multiple connections.
  2. Client Handling:

    • Accepts connections and makes them non-blocking.
    • Reads incoming data until full request is received.
    • Extracts request length from the first 8 bytes.
    • Waits until the full request is read before responding.
    • Sends "MOCK_RESPONSE" and closes the connection.

Performance Enhancements

epoll for High TPS (scalable event loop).

Non-blocking Sockets (handles thousands of clients).

Minimal Memory Copying (only processes request length).

No malloc() or Dynamic Memory (avoids fragmentation).

Auto-closes Connections After Response (mock behavior).

This should easily handle 100K+ TPS on a decent server. 🚀

You would consider multi-threading (SO_REUSEPORT) or io_uring for even higher performance

相关推荐
Dream Algorithm2 小时前
SPN专线+5G业务隔离+工作网+流量共享
网络·5g
jixunwulian2 小时前
智能工业网关 5G/4G通信 硬核配置 视频采集 plc控制
网络·5g
敲键盘的Q5 小时前
【eNSP实战】(续)一个AC多个VAP的实现—将隧道转发改成直接转发
网络
Y.O.U..5 小时前
美团AI面试总结
网络·面试·职场和发展
23zhgjx-LSS5 小时前
ospf单区域
网络·智能路由器
晴空对晚照7 小时前
[动手学习深度学习]26. 网络中的网络 NiN
网络·深度学习·学习
Muisti8 小时前
TCP 通信流程图
服务器·网络·windows
ZZZCY20039 小时前
组播实验--IGMP、IGMP Snooping 及 PIM-DM 协议
网络
IT小饕餮9 小时前
linux 基础网络配置文件
linux·服务器·网络