CGI 的运行原理:

1.客户端访问某个 URL 地址之后,通过 GET/POST/PUT 等方式提交数据,并通过 HTTP 协议向 Web 服务器发出请求。

2.服务器端的 HTTP Daemon(守护进程)启动一个子进程。然后在子进程中,将 HTTP 请求里描述的信息通过标准输入 stdin 和环境变量传递给 URL 指定的 CGI 程序,并启动此应用程序进行处理,处理结果通过标准输出 stdout 返回给 HTTP Daemon 子进程。

再由 HTTP Daemon 子进程通过 HTTP 协议返回给客户端。

#include #include#include#include#include#include#include#include#include

#define SERV_PORT 9003

char *str_join(char *str1, char *str2);char *html_response(char *res, char *buf);int main(void) {intlfd, cfd;structsockaddr_in serv_addr, clin_addr;

socklen_t clin_len;char buf[1024], web_result[1024];intlen;

FILE*cin;if ((lfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {

perror("create socket failed");

exit(1);

}

memset(&serv_addr, 0, sizeof(serv_addr));

serv_addr.sin_family=AF_INET;

serv_addr.sin_addr.s_addr=htonl(INADDR_ANY);

serv_addr.sin_port=htons(SERV_PORT);if (bind(lfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) == -1) {

perror("bind error");

exit(1);

}if (listen(lfd, 128) == -1) {

perror("listen error");

exit(1);

}

signal(SIGCLD, SIG_IGN);while (1) {

clin_len= sizeof(clin_addr);if ((cfd = accept(lfd, (struct sockaddr *) &clin_addr, &clin_len)) == -1) {

perror("接收错误\n");continue;

}

cin= fdopen(cfd, "r");

setbuf(cin, (char *) 0);

fgets(buf,1024, cin); //读取第一行

printf("\n%s", buf);//============================ cgi 环境变量设置演示 ============================//例如 "GET /cgi-bin/user?id=1 HTTP/1.1";

char *delim = " ";char *p;char *method, *filename, *query_string;char *query_string_pre = "QUERY_STRING=";

method= strtok(buf, delim); //GET

p = strtok(NULL, delim); ///user?id=1

filename = strtok(p, "?"); ///user

if (strcmp(filename, "/favicon.ico") == 0) {continue;

}

query_string= strtok(NULL, "?"); //id=1

putenv(str_join(query_string_pre, query_string));//============================ cgi 环境变量设置演示 ============================

int pid =fork();if (pid > 0) {

close(cfd);

}else if (pid == 0) {

close(lfd);

FILE*stream = popen(str_join(".", filename), "r");

fread(buf,sizeof(char), sizeof(buf), stream);

html_response(web_result, buf);

write(cfd, web_result,sizeof(web_result));

pclose(stream);

close(cfd);

exit(0);

}else{

perror("fork error");

exit(1);

}

}

close(lfd);return 0;

}char *str_join(char *str1, char *str2) {char *result = malloc(strlen(str1) + strlen(str2) + 1);if (result == NULL) exit(1);

strcpy(result, str1);

strcat(result, str2);returnresult;

}char *html_response(char *res, char *buf) {char *html_response_template = "HTTP/1.1 200 OK\r\nContent-Type:text/html\r\nContent-Length: %d\r\nServer: mengkang\r\n\r\n%s";

sprintf(res, html_response_template, strlen(buf), buf);returnres;

}

user.c

#include #include

//通过获取的 id 查询用户的信息

int main(void) {//============================ 模拟数据库 ============================

typedef struct{intid;char *username;intage;

} user;

user users[]={

{},

{1,"taoshihan",10}

};//============================ 模拟数据库 ============================

char *query_string;intid;

query_string= getenv("QUERY_STRING");if (query_string ==NULL) {

printf("没有输入数据");

}else if (sscanf(query_string, "id=%d", &id) != 1) {

printf("没有输入id");

}else{

printf("用户信息查询
学号: %d
姓名: %s
年龄: %d", id, users[id].username, users[id].age);

}return 0;

}

访问文件流(stream I/O)的方式进行网络数据传输

1.fdopen:打开一个标准的IO流

原型:FILE *fdopen(int fd, const char *type);

fd是用open函数得到文件描述符,type是打开模式

2.setbuf:定义流 stream 应如何缓冲

原型:void setbuf(FILE *stream, char *buffer)

3.fgets:从指定的流 stream 读取一行,并把它存储在 str 所指向的字符串内,如果成功,该函数返回相同的 str 参数。

原型:char *fgets(char *str, int n, FILE *stream)

处理并传递参数

4.strtok:分解字符串 str 为一组字符串,delim 为分隔符。

原型:char *strtok(char *str, const char *delim)

5.putenv setenv getenv获取设置环境变量相关函数

头文件:#include4

putenv("PATH=/shihan");

char *v=getenv("PATH");

printf("%s\n",v);

拼接字符串

char *str_join(char *str1, char *str2) {

char *result = malloc(strlen(str1) + strlen(str2) + 1);

if (result == NULL) exit(1);

strcpy(result, str1);

strcat(result, str2);

return result;

}

malloc:分配所需的内存空间,并返回一个指向它的指针。

原型:void *malloc(size_t size)

strcpy:把 src 所指向的字符串复制到 dest。

原型:char *strcpy(char *dest, const char *src)

strcat:把 src 所指向的字符串追加到 dest 所指向的字符串的结尾。

char *strcat(char *dest, const char *src)

php 网关接口,[PHP] 通用网关接口CGI 的运行原理相关推荐

  1. [PHP] 通用网关接口CGI 的运行原理

    CGI 的运行原理: 1.客户端访问某个 URL 地址之后,通过 GET/POST/PUT 等方式提交数据,并通过 HTTP 协议向 Web 服务器发出请求. 2.服务器端的 HTTP Daemon( ...

  2. html请求接口_通用网关接口-FastCGI介绍

    一.概述 FastCGI 实际上是增加了一些扩展功能的 CGI .是 CGI 的改进,描述了客户端和Web服务器程序之间传输数据的一种标准. FastCGI 致力于减少Web服务器与CGI程序之间进行 ...

  3. WEB通用网关接口:CGI简单教程

    CGI 全称为Common Gateway Interface (通用网关接口),目的是能够让服务器能够方便的调用外部程序. CGI本身是一套协议和规范,原则上只要是拥有读写文件功能的编程语言都可以用 ...

  4. Java版WMS系统奇门云网关(奇门仓储)接口实现

    基于spring框架 实现的奇门云网关 WMS端 通用API方法: package org.tempuri;import java.io.BufferedReader; import java.io. ...

  5. SpringBoot实现通用的接口参数校验

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 作者:cipher juejin.im/post/5af3c25b ...

  6. 万能通用网关系统!就该这么设计,稳的一批!

    本文准备围绕七个点来讲网关,分别是网关的基本概念.网关设计思路.网关设计重点.流量网关.业务网关.常见网关对比,对基础概念熟悉的朋友可以根据目录查看自己感兴趣的部分. 什么是网关 网关,很多地方将网关 ...

  7. java 接口参数验证_SpringBoot实现通用的接口参数校验

    作者:cipher 来源:http://39sd.cn/560BA 本文介绍基于Spring Boot和JDK8编写一个AOP,结合自定义注解实现通用的接口参数校验. 缘由 目前参数校验常用的方法是在 ...

  8. 实验台通用继电器接口

    ➤ 01继电器接口 1.功能 这是通过蓝牙(hardware)控制的继电器接口.继电器接口的主要功能包括有: 控制信号源的步进继电器,对应的hardware的命令: relayclick 输出三路OC ...

  9. aop+注解 实现对实体类的字段校验_SpringBoot实现通用的接口参数校验

    来自:掘金,作者:cipher 链接:https://juejin.im/post/5af3c25b5188253064651c76 原文链接:http://www.ciphermagic.cn/sp ...

最新文章

  1. 计算机组装与维护实例教程,计算机组装与维护案例教学-20210714101609.pdf-原创力文档...
  2. jenkins自动打包设置打包文件脚本
  3. linux下的拷贝(cp)、删除(rm)、剪切(mv)命令
  4. mysql自带的监控报告_MYSQL监控-自带工具Query Profiler的使用
  5. codevs 3164 质因数分解
  6. 【数据库】防止SQL注入
  7. vagrant --- vagrant部署环境
  8. MaxCompute与OSS非结构化数据读写互通(及图像处理实例)
  9. click group实例
  10. JavaScript高级编程
  11. SQLSERVER 2012之AlwaysOn -- 一次硬件升级引发的问题
  12. HCIE Security 防火墙带宽管理 备考笔记(幕布)
  13. 我也有了博客了,呵呵~~
  14. Atitit js中的依赖注入di ioc的实现
  15. win10计算器rsh_Win10计算器快捷键
  16. mysql +cobar_转:阿里开源Mysql分布式中间件:Cobar
  17. 网页上的广告条设计[zt]
  18. 十年AI学者影响力盘点:何恺明排名第一,成为全球最具影响力学者
  19. 2007年 西安站 东到西开 列车时刻表
  20. CDATA标签的用法

热门文章

  1. foundation 数组NSArray学习
  2. XML 数据挖掘 之 挖掘 XML 关联规则
  3. GridView 合并列、行类
  4. Bailian3717 移动路线【组合】
  5. UVA10912 Simple Minded Hashing【DP】
  6. POJ3619 Speed Reading【水题】
  7. 问题及解决 —— 浏览器问题
  8. Python 进阶 —— 使用修饰器执行函数的参数检查
  9. 机器学习基础(六十一)—— 范数及范数的微分
  10. 学python后到底能干什么-学会Python后都能做什么?网友们的回答简直不要太厉害...