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

如何用C语言构建Linux本地HTTP 1.1服务器,返回200响应并发送index.html

用C语言实现Linux下HTTP/1.1 Web服务器发送HTML响应的方法

你的代码目前存在几个不符合HTTP/1.1规范的问题,导致无法正确返回HTML内容,下面是修正方案和关键说明:

原代码的核心问题

  • 协议版本用了HTTP/1.0,但需求是HTTP/1.1
  • Content-Length写死为2048,和实际文件大小不匹配,会导致客户端解析异常
  • 缺少HTTP/1.1要求的必要响应头(比如Date、Connection、Content-Type)
  • 响应头的换行用了单个换行符,HTTP标准要求必须是\r\n,且响应头和正文之间需要空一行(两个\r\n)

修正后的完整代码

#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <time.h>

// 发送错误响应(404 Not Found)
void send_error(int s) {
    char error_response[] = 
        "HTTP/1.1 404 Not Found\r\n"
        "Server: Linux Web Server\r\n"
        "Date: %s\r\n"
        "Connection: close\r\n"
        "Content-Type: text/html\r\n"
        "Content-Length: 135\r\n"
        "\r\n"
        "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n"
        "<html><head><title>404 Not Found</title></head>\n"
        "<body><h1>Not Found</h1><p>The requested URL was not found on this server.</p></body></html>\n";
    
    // 生成符合HTTP格式的日期字符串
    char date_buf[64];
    time_t now = time(NULL);
    struct tm *tm_info = gmtime(&now);
    strftime(date_buf, sizeof(date_buf), "%a, %d %b %Y %H:%M:%S GMT", tm_info);
    
    char full_response[512];
    sprintf(full_response, error_response, date_buf);
    send(s, full_response, strlen(full_response), 0);
}

// 发送HTML文件的正确响应
void send_data(int s, char *path) { // path='/index.html' 
    char buf[1024];
    char filename[256];
    FILE *send_file;
    struct stat file_stat;
    
    // 拼接文件路径
    sprintf(filename, "htdocs%s", path);
    
    // 获取文件状态,用于获取文件大小
    if (stat(filename, &file_stat) != 0) {
        send_error(s);
        return;
    }
    
    // 打开文件
    send_file = fopen(filename, "rb");
    if (send_file == NULL) {
        send_error(s);
        return;
    }
    
    // 生成HTTP响应头
    char response_header[512];
    char date_buf[64];
    time_t now = time(NULL);
    struct tm *tm_info = gmtime(&now);
    strftime(date_buf, sizeof(date_buf), "%a, %d %b %Y %H:%M:%S GMT", tm_info);
    
    sprintf(response_header,
        "HTTP/1.1 200 OK\r\n"
        "Server: Linux Web Server\r\n"
        "Date: %s\r\n"
        "Connection: close\r\n"
        "Content-Type: text/html\r\n"
        "Content-Length: %ld\r\n"
        "\r\n",
        date_buf, file_stat.st_size
    );
    
    // 发送响应头
    send(s, response_header, strlen(response_header), 0);
    
    // 发送文件内容
    int len;
    while ((len = fread(buf, 1, sizeof(buf), send_file)) > 0) {
        send(s, buf, len, 0);
    }
    
    fclose(send_file);
}

关键要点说明

  • HTTP/1.1协议合规:响应头开头明确用HTTP/1.1 200 OK,所有头字段用\r\n分隔,头和正文之间用空行(\r\n\r\n)分隔
  • 动态计算Content-Length:通过stat函数获取文件的真实大小,避免写死数值导致的解析错误
  • 添加必要响应头:
    • Date:必须包含的HTTP头,用GMT格式的当前时间
    • Connection: close:告诉客户端响应结束后关闭连接(适合简单服务器)
    • Content-Type: text/html:明确告诉客户端返回的是HTML内容
  • 错误处理完善:无论是文件不存在还是打开失败,都返回标准的404错误响应
  • 文件读取优化:用二进制模式打开文件,避免文本模式下的换行符转换问题,确保文件内容完整发送

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 11:45:38