You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于fork的C语言登录服务器多次连接无响应问题排查

问题分析与修复方案

核心问题

  1. 共享文件描述符冲突:父进程打开的文件描述符被所有子进程共享,子进程通过fdopen创建的FILE指针会互相干扰文件偏移量,导致读取位置错误,无法正确处理请求。
  2. 未处理网络调用错误:recv/send未检查返回值,数据传输失败时直接进入后续逻辑,导致无响应。
  3. 父进程过早关闭客户端Socket:fork后父进程立刻关闭Socket,可能导致子进程Socket被意外销毁。
  4. 无文件锁机制:多进程同时读写TXT文件,出现竞态条件,读取到不完整数据。
  5. 字符串长度计算错误:服务器中send的字符串与strlen参数大小写不一致,导致发送内容不完整。
  6. 未初始化addr_size:accept调用时addr_size未赋值,可能引发未定义行为。

修复步骤

1. 每个子进程独立打开文件

移除全局FILE* fp,子进程内单独打开数据库文件,避免共享文件偏移:

if ((childpid = fork()) == 0){
    // ... 初始化代码
    FILE *local_fp = fopen("baza.txt", "a+");
    if (!local_fp) {
        perror("无法打开数据库文件");
        send(client_socket, "服务器内部错误", strlen("服务器内部错误"), 0);
        close(client_socket);
        exit(EXIT_FAILURE);
    }
    // ... 后续逻辑
}

2. 检查网络调用返回值

每次recv/send都要验证结果,处理错误:

// 示例:接收决策指令
ssize_t recv_len = recv(client_socket, decision, sizeof(decision)-1, 0);
if (recv_len == -1) {
    perror("接收数据失败");
    close(client_socket);
    fclose(local_fp);
    exit(EXIT_FAILURE);
}
decision[recv_len] = '\0'; // 确保字符串以'\0'结尾

3. 处理僵尸进程并延迟Socket关闭

添加SIGCHLD信号处理,避免僵尸进程,父进程无需立刻关闭客户端Socket:

void sigchld_handler(int sig) {
    while (waitpid(-1, NULL, WNOHANG) > 0);
}

int main() {
    signal(SIGCHLD, sigchld_handler);
    // ... 初始化代码
}

4. 添加文件锁

使用flock确保同一时间只有一个进程读写文件:

#include <sys/file.h>

// 打开文件后加排他锁
if (flock(fileno(local_fp), LOCK_EX) == -1) {
    perror("文件加锁失败");
    fclose(local_fp);
    close(client_socket);
    exit(EXIT_FAILURE);
}

// ... 读写操作完成后解锁
flock(fileno(local_fp), LOCK_UN);

5. 修复字符串长度bug

修正send中的字符串长度参数,确保大小写一致:

send(client_socket,"Znaleziono login",strlen("Znaleziono login"),0);

6. 初始化addr_size

accept前赋值addr_size:

socklen_t addr_size = sizeof(client_address);
int client_socket = accept(server_socket, (struct sockaddr*)&client_address, &addr_size);

内容的提问来源于stack exchange,提问作者Karol Hynek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 23:10:27