TCP并发实现

文章目录

TCP服务端

基础服务端

c 复制代码
// 基础TCP服务器核心流程
#define BUFFER_SIZE 1024  // 根据设备内存自定义
char buf[BUFFER_SIZE];

int main() {
    // 1. 创建socket
    fd = socket(AF_INET, SOCK_STREAM, 0);
    
    // 2. 准备地址结构
    addr.sin_family = AF_INET;
    addr.sin_port = htons(PORT);
    addr.sin_addr.s_addr = 0;  // INADDR_ANY的另一种写法
    
    // 3. 绑定地址
    bind(fd, (struct sockaddr *)&addr, sizeof(addr));
    
    // 4. 开始监听
    listen(fd, BACKLOG);
    
    // 5. 接受连接(阻塞等待)
    newfd = accept(fd, NULL, NULL);  // 不关心客户端地址
    
    // 6. 接收数据
    read(newfd, buf, BUFFER_SIZE);
    
    // 7. 关闭连接
    close(newfd);
    close(fd);
    return 0;
}

TCP服务设计模式

迭代服务(一次处理一个客户端)

c 复制代码
// 简化的迭代服务器框架
while (1) {
    client_fd = accept(server_fd, NULL, NULL);
    if (client_fd < 0) continue;
    
    handle_client(client_fd);  // 处理客户端请求
    
    close(client_fd);  // 处理完后关闭
}

缺点:无法并发处理多个客户端

多进程并发服务

c 复制代码
// 父进程:监听连接,创建子进程处理
// 子进程:处理具体客户端请求,结束后退出

pid_t pid = fork();
if (pid == 0) {
    // 子进程
    close(server_fd);  // 关闭不需要的监听socket
    handle_client(client_fd);
    close(client_fd);
    exit(0);  // 子进程结束
} else {
    // 父进程
    close(client_fd);  // 父进程关闭已分发的客户端socket
    waitpid(-1, NULL, WNOHANG);  // 非阻塞回收子进程
}
僵尸进程处理(信号处理)
c 复制代码
// 使用信号处理函数回收子进程
void sigchld_handler(int sig) {
    while (waitpid(-1, NULL, WNOHANG) > 0) {
        // 回收所有已终止的子进程
    }
}

// 注册信号处理器
signal(SIGCHLD, sigchld_handler);

// 更推荐使用sigaction(可重启系统调用)
struct sigaction sa;
sa.sa_handler = sigchld_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART | SA_NOCLDSTOP;
sigaction(SIGCHLD, &sa, NULL);

多线程并发服务

c 复制代码
// 主线程:监听连接,创建子线程
// 工作线程:处理客户端请求

void *client_handler(void *arg) {
    int client_fd = *(int *)arg;
    // 处理客户端...
    close(client_fd);
    return NULL;
}

// 创建线程处理每个客户端
pthread_t tid;
int *client_fd_ptr = malloc(sizeof(int));
*client_fd_ptr = client_fd;
pthread_create(&tid, NULL, client_handler, client_fd_ptr);
pthread_detach(tid);  // 分离线程,自动回收资源
嵌入式设备线程注意
c 复制代码
// 1. 设置线程栈大小(嵌入式内存有限)
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, 8192);  // 8KB栈空间

// 2. 线程池模式(避免频繁创建销毁线程)
// 3. 注意线程安全,共享数据加锁

TCP客户端

基础客户端

c 复制代码
// 核心流程
int main() {
    // 1. 创建socket
    fd = socket(AF_INET, SOCK_STREAM, 0);
    
    // 2. 设置服务器地址
    addr.sin_family = AF_INET;
    addr.sin_port = htons(PORT);
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    
    // 3. 连接服务器
    connect(fd, (struct sockaddr *)&addr, sizeof(addr));
    
    // 4. 发送数据
    write(fd, STR, sizeof(STR));
    
    // 5. 关闭连接
    close(fd);
}

交互式客户端

c 复制代码
// 支持命令行参数和交互式输入
int main(int argc, char *argv[]) {
    // 检查参数
    if (argc < 3) {
        fprintf(stderr, "用法: %s <IP地址> <端口>\n", argv[0]);
        exit(EXIT_FAILURE);
    }
    
    // 解析参数
    char *server_ip = argv[1];
    int server_port = atoi(argv[2]);
    
    // 创建socket和连接...
    
    // 交互循环
    while (1) {
        printf("请输入消息: ");
        fgets(buf, BUFSIZ, stdin);
        
        // 发送数据
        int n = write(fd, buf, strlen(buf));
        if (n <= 0) {
            perror("发送失败");
            break;
        }
        
        // 可选:接收服务器响应
        // n = read(fd, response, sizeof(response));
    }
}

客户端断线重连机制

c 复制代码
// 嵌入式设备常用,增加连接稳定性
#define MAX_RETRY 5
#define RETRY_DELAY 3  // 秒

int connect_with_retry(const char *ip, int port, int max_retry) {
    int sockfd;
    struct sockaddr_in addr;
    
    for (int retry = 0; retry < max_retry; retry++) {
        sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (sockfd < 0) {
            perror("创建socket失败");
            return -1;
        }
        
        memset(&addr, 0, sizeof(addr));
        addr.sin_family = AF_INET;
        addr.sin_port = htons(port);
        inet_pton(AF_INET, ip, &addr.sin_addr);
        
        if (connect(sockfd, (struct sockaddr*)&addr, sizeof(addr)) == 0) {
            printf("连接成功(第%d次尝试)\n", retry + 1);
            return sockfd;
        }
        
        close(sockfd);
        printf("连接失败,%d秒后重试...\n", RETRY_DELAY);
        sleep(RETRY_DELAY);
    } 
    
    fprintf(stderr, "连接失败,达到最大重试次数\n");
    return -1;
}
相关推荐
MrSYJ4 天前
TCP协议理解
后端·tcp/ip
zzzzzz31011 天前
9K Star 炸裂开源!这个 C 语言写的代码知识图谱,把 Linux 内核索引压缩到了 3 分钟
linux·服务器·sql
大树8815 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
小宇宙Zz15 天前
Maven依赖冲突
java·服务器·maven
网络研究院15 天前
2026年网络安全
网络·安全·法律·法规·趋势·发展
酣大智15 天前
ARP代理--工作原理
运维·网络·arp·arp代理
treesforest15 天前
AI安全系统如何识别异常访问?IP风险识别正在成为关键能力
网络·人工智能·tcp/ip·安全·web安全
shushangyun_15 天前
2026年快消品B2B系统推荐:支持终端门店订货、促销政策自动化的工具?
java·运维·网络·数据库·人工智能·spring·自动化
古城小栈15 天前
Unix 与 Linux 异同小叙
linux·服务器·unix
2601_9618451515 天前
粉笔行测题库|系统班|刷题
网络·百度·微信·微信公众平台·facebook·新浪微博