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

相关推荐
今天背单词了吗9806 分钟前
AI 网关:大模型时代的统一接入与安全防线
网络·人工智能·安全·ai·1024程序员节
CodeGL14 分钟前
13、Python基础之网络编程
网络·1024程序员节
lazy H19 分钟前
【计算机网络】第 5 篇:TCP 和 UDP 有什么区别?从 Java 后端场景理解两种传输协议
经验分享·后端·网络协议·tcp/ip·计算机网络·1024程序员节
星恒随风1 小时前
Linux网络编程基础(二):彻底理解局域网通信、MAC与IP地址、数据封装、端口号、网络字节序及Socket接口
linux·网络·笔记·学习·tcp/ip·1024程序员节
CHHH_HHH2 小时前
【Linux网络篇】初识网络与Socket编程基础
linux·服务器·c语言·开发语言·网络·后端·1024程序员节
weixin_417396832 小时前
老酒店有线电视改造怎么做?三种路径对比与施工节奏
网络·技术·酒店·1024程序员节·综合布线·弱电
pt10432 小时前
Cisco设备网络安全系列-12:Web服务器防护与WAF应用
网络·安全
jimmyleeee2 小时前
Agent安全之一:Agent Goal Hijack(ASI01)----当智能体“正确地”执行了错误的目标
运维·网络·安全
byte轻骑兵3 小时前
【LMP】规范精讲[8]: 主从易位——角色切换的时序反转与微微网重构
网络协议·安全·蓝牙协议·lmp·链接管理
Sirens.3 小时前
网络通信基础:IP、端口、协议分层与数据封装
java·网络·网络协议·tcp/ip·java-ee·1024程序员节