跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C

C语言Web开发:CGI、FastCGI与Nginx详解

C语言Web开发涉及CGI、FastCGI及Nginx模块。CGI用于服务器与程序通信但性能较低;FastCGI通过进程驻留提升性能;Nginx支持事件驱动模型与内存池管理。内容包含C语言编写CGI、FastCGI及Nginx模块的代码示例,涵盖参数获取、用户登录实战及配置方法,帮助开发者掌握高性能Web服务构建。

怪力乱神发布于 2026/3/23更新于 2026/8/2438 浏览
C语言Web开发:CGI、FastCGI与Nginx详解

C语言Web开发:CGI、FastCGI与Nginx详解

一、前言:为什么 Web 开发是 C 语言开发的重要技能?

学习目标
  • 理解Web 开发的本质:编写程序实现 Web 应用、服务器端逻辑和客户端交互
  • 明确 Web 开发的重要性:支撑互联网、电子商务、社交网络等领域的发展
  • 掌握本章学习重点:CGI、FastCGI、Nginx 的开发方法、避坑指南、实战案例分析
  • 学会使用 C 语言开发 Web 应用,实现服务器端逻辑和客户端交互
重点提示

💡 Web 开发是 C 语言开发的重要技能!随着互联网的普及,Web 开发的需求越来越大,C 语言的高性能和可移植性使其在 Web 开发中具有重要地位。


二、模块 1:CGI(通用网关接口)基础

2.1 学习目标
  • 理解CGI的本质:通用网关接口,用于 Web 服务器与服务器端程序之间的通信
  • 掌握CGI 的核心架构:Web 服务器、CGI 程序、客户端
  • 掌握CGI 的开发方法:使用 C 语言编写 CGI 程序
  • 掌握CGI 的避坑指南:避免环境变量未设置、避免输出格式错误、避免资源泄漏
  • 避开 CGI 使用的 3 大常见坑
2.2 CGI 的核心架构

Web 服务器:接受客户端请求,将请求转发给 CGI 程序
CGI 程序:处理请求,生成响应
客户端:发送请求,接收响应

2.3 CGI 的开发方法

代码示例 1:CGI 程序——简单的 Hello World

#include <stdio.h>
#include <stdlib.h>

int main() {
    // 设置 HTTP 响应头
    printf("Content-Type: text/plain\n\n");
    // 输出响应内容
    printf("Hello from CGI!");
    return 0;
}

代码示例 2:CGI 程序——获取 HTTP 请求参数

#include <stdio.h>
# 


  {
     i = , j = ;
     (src[i]) {
         (src[i] == ) {
             value;
            (src + i + , , &value);
            dst[j++] = ()value;
            i += ;
        }   (src[i] == ) {
            dst[j++] = ;
            i++;
        }  {
            dst[j++] = src[i++];
        }
    }
    dst[j] = ;
}

  {
    
    * query_string = getenv();
    * content_type = getenv();
    * request_method = getenv();

    
    ();
    (, query_string ? query_string : );
    (, content_type ? content_type : );
    (, request_method ? request_method : );

     ((request_method, ) ==  && query_string) {
        * token = strtok(query_string, );
         (token) {
            * equals = (token, );
             (equals) {
                *equals = ;
                * key = token;
                * value = equals + ;
                 decoded_key[], decoded_value[];
                decode_url(key, decoded_key);
                decode_url(value, decoded_value);
                (, decoded_key, decoded_value);
            }
            token = strtok(, );
        }
    }
     ;
}
include
<stdlib.h>
#include <string.h>
void
decode_url
(char* src, char* dst)
int
0
0
while
if
'%'
int
sscanf
1
"%2x"
char
3
else
if
'+'
' '
else
'\0'
int
main
()
// 获取环境变量
char
"QUERY_STRING"
char
"CONTENT_TYPE"
char
"REQUEST_METHOD"
// 输出环境变量信息
printf
"Content-Type: text/plain\n\n"
printf
"Query String: %s\n"
""
printf
"Content Type: %s\n"
""
printf
"Request Method: %s\n"
""
if
strcmp
"GET"
0
char
"&"
while
char
strchr
'='
if
'\0'
char
char
1
char
100
100
printf
"Parameter: %s = %s\n"
NULL
"&"
return
0

三、模块 2:FastCGI(快速通用网关接口)基础

3.1 学习目标
  • 理解FastCGI的本质:快速通用网关接口,改进了 CGI 的性能
  • 掌握FastCGI 的核心架构:Web 服务器、FastCGI 进程、客户端
  • 掌握FastCGI 的开发方法:使用 C 语言编写 FastCGI 程序
  • 掌握FastCGI 的避坑指南:避免进程管理错误、避免通信错误、避免资源泄漏
  • 避开 FastCGI 使用的 3 大常见坑
3.2 FastCGI 的核心架构

Web 服务器:接受客户端请求,将请求转发给 FastCGI 进程
FastCGI 进程:处理请求,生成响应,保持进程驻留以提高性能
客户端:发送请求,接收响应

3.3 FastCGI 的开发方法

代码示例 3:FastCGI 程序——简单的 Hello World

#include <fcgi_stdio.h>
#include <stdlib.h>

int main() {
    while (FCGI_Accept() >= 0) {
        // 设置 HTTP 响应头
        printf("Content-Type: text/plain\n\n");
        // 输出响应内容
        printf("Hello from FastCGI!");
    }
    return 0;
}

代码示例 4:FastCGI 程序——获取 HTTP 请求参数

#include <fcgi_stdio.h>
#include <stdlib.h>
#include <string.h>

void decode_url(char* src, char* dst) {
    int i = 0, j = 0;
    while (src[i]) {
        if (src[i] == '%') {
            int value;
            sscanf(src + i + 1, "%2x", &value);
            dst[j++] = (char)value;
            i += 3;
        } else if (src[i] == '+') {
            dst[j++] = ' ';
            i++;
        } else {
            dst[j++] = src[i++];
        }
    }
    dst[j] = '\0';
}

int main() {
    while (FCGI_Accept() >= 0) {
        // 获取环境变量
        char* query_string = getenv("QUERY_STRING");
        char* content_type = getenv("CONTENT_TYPE");
        char* request_method = getenv("REQUEST_METHOD");

        // 输出环境变量信息
        printf("Content-Type: text/plain\n\n");
        printf("Query String: %s\n", query_string ? query_string : "");
        printf("Content Type: %s\n", content_type ? content_type : "");
        printf("Request Method: %s\n", request_method ? request_method : "");

        if (strcmp(request_method, "GET") == 0 && query_string) {
            char* token = strtok(query_string, "&");
            while (token) {
                char* equals = strchr(token, '=');
                if (equals) {
                    *equals = '\0';
                    char* key = token;
                    char* value = equals + 1;
                    char decoded_key[100], decoded_value[100];
                    decode_url(key, decoded_key);
                    decode_url(value, decoded_value);
                    printf("Parameter: %s = %s\n", decoded_key, decoded_value);
                }
                token = strtok(NULL, "&");
            }
        }
    }
    return 0;
}

四、模块 3:Nginx 与 C 语言开发基础

4.1 学习目标
  • 理解Nginx的本质:高性能 Web 服务器和反向代理服务器
  • 掌握Nginx 的核心架构:事件驱动模型、内存池、多进程模型
  • 掌握Nginx 的开发方法:使用 C 语言编写 Nginx 模块
  • 掌握Nginx 的避坑指南:避免模块编译错误、避免内存泄漏、避免线程安全问题
  • 避开 Nginx 使用的 3 大常见坑
4.2 Nginx 的核心架构

事件驱动模型:使用 epoll 等事件通知机制,高效处理并发连接
内存池:统一管理内存分配和释放,避免内存泄漏
多进程模型:Master 进程管理 Worker 进程,Worker 进程处理请求

4.3 Nginx 的开发方法

代码示例 5:Nginx 模块——简单的 Hello World

#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>

static ngx_int_t ngx_http_hello_handler(ngx_http_request_t *r);
static ngx_command_t ngx_http_hello_commands[] = {
    {ngx_string("hello_world"), NGX_HTTP_LOC_CONF | NGX_CONF_NOARGS, ngx_conf_set_flag_slot, NGX_HTTP_LOC_CONF_OFFSET, 0, NULL},
    ngx_null_command
};
static ngx_http_module_t ngx_http_hello_module_ctx = {
    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
ngx_module_t ngx_http_hello_module = {
    NGX_MODULE_V1,
    &ngx_http_hello_module_ctx,
    ngx_http_hello_commands,
    NGX_HTTP_MODULE,
    NULL, NULL, NULL, NULL, NULL, NULL, NULL,
    NGX_MODULE_V1_PADDING
};

static ngx_int_t ngx_http_hello_handler(ngx_http_request_t *r) {
    ngx_int_t rc;
    ngx_buf_t *b;
    ngx_chain_t out;

    // 设置响应头
    r->headers_out.content_type.len = sizeof("text/plain") - 1;
    r->headers_out.content_type.data = (u_char *)"text/plain";
    r->headers_out.status = NGX_HTTP_OK;
    r->headers_out.content_length_n = 13;

    // 发送响应头
    rc = ngx_http_send_header(r);
    if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
        return rc;
    }

    // 准备响应内容
    b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
    if (b == NULL) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }
    out.buf = b;
    out.next = NULL;
    b->pos = (u_char *)"Hello from Nginx!";
    b->last = b->pos + 13;
    b->memory = 1;
    b->last_buf = 1;

    // 发送响应内容
    return ngx_http_output_filter(r, &out);
}

static ngx_int_t ngx_http_hello_init(ngx_conf_t *cf) {
    ngx_http_handler_pt *h;
    ngx_http_core_loc_conf_t *clcf;
    clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
    h = ngx_array_push(&clcf->handlers);
    if (h == NULL) {
        return NGX_ERROR;
    }
    *h = ngx_http_hello_handler;
    return NGX_OK;
}

static ngx_http_module_t ngx_http_hello_module_ctx = {
    NULL, ngx_http_hello_init, NULL, NULL, NULL, NULL, NULL, NULL
};

五、模块 4:实战案例分析——使用 C 语言实现简单的 Web 应用

5.1 学习目标
  • 掌握使用 C 语言实现简单的 Web 应用:通过 Nginx 和 FastCGI 实现一个简单的 Web 应用
  • 学会使用 FastCGI 程序处理 HTTP 请求,解析参数,生成响应
  • 避开实战案例使用的 3 大常见坑
5.2 使用 C 语言实现简单的 Web 应用

代码示例 6:FastCGI 程序——用户登录

#include <fcgi_stdio.h>
#include <stdlib.h>
#include <string.h>

void decode_url(char* src, char* dst) {
    int i = 0, j = 0;
    while (src[i]) {
        if (src[i] == '%') {
            int value;
            sscanf(src + i + 1, "%2x", &value);
            dst[j++] = (char)value;
            i += 3;
        } else if (src[i] == '+') {
            dst[j++] = ' ';
            i++;
        } else {
            dst[j++] = src[i++];
        }
    }
    dst[j] = '\0';
}

int main() {
    while (FCGI_Accept() >= 0) {
        // 获取环境变量
        char* content_type = getenv("CONTENT_TYPE");
        char* request_method = getenv("REQUEST_METHOD");

        if (strcmp(request_method, "POST") == 0) {
            // 获取请求体长度
            char* content_length_str = getenv("CONTENT_LENGTH");
            int content_length = atoi(content_length_str);

            // 读取请求体
            char* post_data = (char*)malloc(content_length + 1);
            if (post_data) {
                fread(post_data, 1, content_length, stdin);
                post_data[content_length] = '\0';

                // 解析请求体参数
                char* username = NULL;
                char* password = NULL;
                char* token = strtok(post_data, "&");
                while (token) {
                    char* equals = strchr(token, '=');
                    if (equals) {
                        *equals = '\0';
                        char* key = token;
                        char* value = equals + 1;
                        char decoded_key[100], decoded_value[100];
                        decode_url(key, decoded_key);
                        decode_url(value, decoded_value);
                        if (strcmp(decoded_key, "username") == 0) {
                            username = strdup(decoded_value);
                        } else if (strcmp(decoded_key, "password") == 0) {
                            password = strdup(decoded_value);
                        }
                    }
                    token = strtok(NULL, "&");
                }

                // 验证用户
                printf("Content-Type: text/plain\n\n");
                if (username && password && strcmp(username, "admin") == 0 && strcmp(password, "123456") == 0) {
                    printf("登录成功!");
                } else {
                    printf("用户名或密码错误!");
                }
                free(username);
                free(password);
                free(post_data);
            }
        } else {
            // 发送登录页面
            printf("Content-Type: text/html\n\n");
            printf("<html>");
            printf("<head>");
            printf("<title>登录页面</title>");
            printf("</head>");
            printf("<body>");
            printf("<h1>用户登录</h1>");
            printf("<form method='post' action='/login'>");
            printf("用户名:<input type='text' name='username'><br>");
            printf("密码:<input type='password' name='password'><br>");
            printf("<input type='submit' value='登录'>");
            printf("</form>");
            printf("</body>");
            printf("</html>");
        }
    }
    return 0;
}

Nginx 配置文件示例:

server {
    listen 80;
    server_name localhost;

    location / {
        root html;
        index index.html;
    }

    location /login {
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.cgi;
        include fastcgi_params;
    }
}

六、本章总结与课后练习

6.1 总结

✅ CGI 网络编程:通用网关接口,用于 Web 服务器与服务器端程序之间的通信
✅ FastCGI 网络编程:改进了 CGI 的性能,支持进程驻留
✅ Nginx 与 C 语言开发:高性能 Web 服务器和反向代理服务器,支持模块开发
✅ 实战案例分析:使用 C 语言实现简单的 Web 应用,包含登录功能

6.2 课后练习
  1. 编写程序:实现一个简单的 CGI 程序,输出当前时间
  2. 编写程序:实现一个简单的 CGI 程序,获取 HTTP 请求的 Cookie
  3. 编写程序:实现一个简单的 FastCGI 程序,输出当前时间
  4. 编写程序:实现一个简单的 FastCGI 程序,获取 HTTP 请求的 Cookie
  5. 编写程序:实现一个简单的 Nginx 模块,输出当前时间
  6. 编写程序:实现一个简单的 Nginx 模块,获取 HTTP 请求的 Cookie
  7. 编写程序:实现一个简单的 Web 应用,包含用户注册和登录功能
  8. 编写程序:实现一个简单的 Web 应用,包含数据存储和查询功能
  9. 编写程序:实现一个简单的 Web 应用,包含文件上传和下载功能
  10. 编写程序:实现一个简单的 Web 应用,包含 WebSocket 通信功能

目录

  1. C语言Web开发:CGI、FastCGI与Nginx详解
  2. 一、前言:为什么 Web 开发是 C 语言开发的重要技能?
  3. 学习目标
  4. 重点提示
  5. 二、模块 1:CGI(通用网关接口)基础
  6. 2.1 学习目标
  7. 2.2 CGI 的核心架构
  8. 2.3 CGI 的开发方法
  9. 三、模块 2:FastCGI(快速通用网关接口)基础
  10. 3.1 学习目标
  11. 3.2 FastCGI 的核心架构
  12. 3.3 FastCGI 的开发方法
  13. 四、模块 3:Nginx 与 C 语言开发基础
  14. 4.1 学习目标
  15. 4.2 Nginx 的核心架构
  16. 4.3 Nginx 的开发方法
  17. 五、模块 4:实战案例分析——使用 C 语言实现简单的 Web 应用
  18. 5.1 学习目标
  19. 5.2 使用 C 语言实现简单的 Web 应用
  20. 六、本章总结与课后练习
  21. 6.1 总结
  22. 6.2 课后练习
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 谷歌发布乒乓球 AI 机器人,实现正反手灵活转换与中级选手水平对抗
  • 基于 Web 的红色旅游网站的设计与实现
  • 本地 Qwen 与 ComfyUI 制作 AI 漫剧教程
  • TRAE AI 编程:从工具入门到 Vue 全栈实战
  • Step3-VL-10B 多模态推理:电商详情页自动化文案与 SEO 优化
  • C++ 多态进阶:纯虚函数、抽象类与虚函数表底层原理
  • Python Tkinter 集成 DocsGPT 开发 AI 代码助手
  • Linux/Debian 系统时间校准方法简记
  • 苍穹外卖实战:Spring Task 定时任务与 WebSocket 应用
  • C++ 基于正倒排索引的 Boost 搜索引擎实战
  • 大模型本地部署的电脑硬件配置指南
  • AgentScope Java:阿里开源的 LLM 智能体框架
  • Python 类型注解详解:AI 大模型开发实战
  • HarmonyOS 6.0 Camera Kit 微距状态监听详解
  • 基于 Spring Boot 的学生成绩管理系统设计与实现
  • 大语言模型智能体 (LLM Agents) 入门指南
  • FPGA 实现 FIR 滤波器实战详解:从原理到代码
  • AI 数据标注平台的选型与实践:效率提升背后的技术逻辑
  • Trae 安装与上手:一款 AI 原生 IDE 的实际体验
  • LLaMA-Factory 微调显存参考表:7B 到 72B 模型实测

相关免费在线工具

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online

  • JSON美化和格式化

    将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online