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

C语言循环监听socket的简易HTTP服务器代码问题排查

极简HTTP服务器Socket逻辑异常排查

问题原始代码

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <pthread.h>
#include <arpa/inet.h>

struct sockaddr_in server, acc;
int sock;

int stuff(void) {
    char buffer[2000];

    recv(sock, buffer, sizeof(buffer), 0);
    send(sock, "HTTP/1.1 200 OK\nContent-Type: text/html\n\nHello", sizeof("HTTP/1.1 200 OK\nContent-Type: text/html\n\nHello"), 0);

    shutdown(sock, SHUT_RDWR);
    
    return 0;
}

int main(void) {
    int size;

    sock = socket(AF_INET, SOCK_STREAM, 0);

    server.sin_family      = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port        = htons(1111);

    if (bind(sock, (struct sockaddr*)&server, sizeof(server)) == -1) {
        perror("Error:");
        return 1;
    }

    while (1) {
        listen(sock, 5);
        sock = accept(sock, (struct sockaddr*)&acc, &size);
        printf("accepted\n");

        stuff();

        close(sock);
    }
}

故障表现

  • 客户端连接无法正常终止,浏览器访问服务时页面持续加载无响应
  • 控制台循环打印第42行的accepted日志
  • 服务无法正常处理新的连接请求

根因分析

代码存在4个核心逻辑错误,直接导致所有异常现象:

  • 套接字变量混用覆盖:全局变量sock一开始存储的是绑定1111端口的监听套接字,但第一次调用accept时,直接将函数返回的已连接套接字赋值给了sock,原始监听套接字的文件描述符被覆盖丢失。后续循环再调用listen、accept时,操作的都是和客户端通信的已连接套接字,而非监听套接字,逻辑完全失效。同时代码未检查任何系统调用的返回值,哪怕accept调用失败返回-1,也会直接打印日志进入后续流程,导致控制台循环输出accepted。
  • accept参数未初始化且类型错误:accept的第三个参数要求传入指向socklen_t类型的指针,且指针指向的值必须提前初始化为客户端地址结构体acc的长度。代码中int size;是未初始化的栈变量,存储的是随机垃圾值,直接导致accept行为不可控。
  • listen调用位置错误:listen的作用是将套接字标记为被动监听状态,只需要在bind成功后、进入连接接收循环前调用1次即可。代码将listen放在循环内部反复调用,在套接字被覆盖为已连接套接字后,这些调用本身就是无效操作。
  • HTTP响应格式不符合规范:返回的响应头使用\n作为行分隔符,而HTTP标准要求行结束符必须是\r\n;同时响应没有携带Content-Length或Connection: close标识,浏览器无法判断响应是否已经传输完成,会一直保持连接等待后续数据,表现为页面持续加载。

修复方向

  • 拆分套接字变量:单独定义监听套接字变量和每次接收连接生成的已连接套接字变量,禁止混用覆盖
  • 进入循环前调用一次listen,不要在循环内重复调用
  • 初始化accept所需的地址长度参数,使用正确的socklen_t类型传参
  • 为所有系统调用添加返回值检查,出错时打印错误信息及时感知问题
  • 按照HTTP规范调整响应格式,使用标准换行符,添加Connection: close头明确告知客户端响应结束可以关闭连接

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 04:48:33