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;
}
相关推荐
随身数智备忘录1 小时前
什么是设备管理体系?设备管理体系包含哪些核心模块?
网络·数据库·人工智能
第五文修2 小时前
手机OTG转TTL网口实现ping功能
网络·智能手机
189228048612 小时前
NY352固态MT29F32T08GWLBHD6-24QJ:B
大数据·服务器·人工智能·科技·缓存
AI视觉网奇2 小时前
linux 检索库 判断库是否支持
java·linux·服务器
云边云科技_云网融合2 小时前
企业大模型时代的网络架构五层演进:从连接到智能的范式重构
网络·重构·架构
一楼的猫3 小时前
从工具链视角对比:番茄作家助手 vs 第三方写作辅助方案
java·服务器·开发语言·前端·学习·chatgpt·ai写作
武子康3 小时前
调查研究-138 全球机器人产业深度调研报告【01 篇】:市场规模、竞争格局与商业化成熟 2026
服务器·数据库·ai·chatgpt·机器人·具身智能
xhbh6664 小时前
代理ARP (Proxy ARP) 是如何实现跨网段通信的?在Linux下如何配置?
服务器·网络·智能路由器·端口映射·映射
神奇椰子5 小时前
[特殊字符] 服务器搭建网站完整教程
运维·服务器
数智化管理手记5 小时前
精益生产3步实操,让现场从混乱变标杆
大数据·运维·网络·人工智能·精益工程