日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > php >内容正文

php

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

發(fā)布時間:2025/3/20 php 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [PHP] 通用网关接口CGI 的运行原理 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

CGI 的運行原理:
1.客戶端訪問某個 URL 地址之后,通過 GET/POST/PUT 等方式提交數(shù)據(jù),并通過 HTTP 協(xié)議向 Web 服務器發(fā)出請求。
2.服務器端的 HTTP Daemon(守護進程)啟動一個子進程。然后在子進程中,將 HTTP 請求里描述的信息通過標準輸入 stdin 和環(huán)境變量傳遞給 URL 指定的 CGI 程序,并啟動此應用程序進行處理,處理結果通過標準輸出 stdout 返回給 HTTP Daemon 子進程。
再由 HTTP Daemon 子進程通過 HTTP 協(xié)議返回給客戶端。

#include <stdio.h> #include <stdlib.h> #include <signal.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netinet/in.h> #include <string.h>#define SERV_PORT 9003char *str_join(char *str1, char *str2);char *html_response(char *res, char *buf);int main(void) {int lfd, cfd;struct sockaddr_in serv_addr, clin_addr;socklen_t clin_len;char buf[1024], web_result[1024];int len;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 環(huán)境變量設置演示 ============================// 例如 "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); // GETp = strtok(NULL, delim); // /user?id=1 filename = strtok(p, "?"); // /userif (strcmp(filename, "/favicon.ico") == 0) {continue;}query_string = strtok(NULL, "?"); // id=1 putenv(str_join(query_string_pre, query_string));//============================ cgi 環(huán)境變量設置演示 ============================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);return result; }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);return res; }

user.c

#include <stdio.h> #include <stdlib.h>// 通過獲取的 id 查詢用戶的信息 int main(void) {//============================ 模擬數(shù)據(jù)庫 ============================typedef struct {int id;char *username;int age;} user;user users[] = {{},{1,"taoshihan",10}};//============================ 模擬數(shù)據(jù)庫 ============================char *query_string;int id;query_string = getenv("QUERY_STRING");if (query_string == NULL) {printf("沒有輸入數(shù)據(jù)");} else if (sscanf(query_string, "id=%d", &id) != 1) {printf("沒有輸入id");} else {printf("用戶信息查詢<br>學號: %d<br>姓名: %s<br>年齡: %d", id, users[id].username, users[id].age);}return 0; }

?

?

訪問文件流(stream I/O)的方式進行網(wǎng)絡數(shù)據(jù)傳輸
1.fdopen:打開一個標準的IO流
原型:FILE *fdopen(int fd, const char *type);
fd是用open函數(shù)得到文件描述符,type是打開模式

2.setbuf:定義流 stream 應如何緩沖
原型:void setbuf(FILE *stream, char *buffer)

3.fgets:從指定的流 stream 讀取一行,并把它存儲在 str 所指向的字符串內(nèi),如果成功,該函數(shù)返回相同的 str 參數(shù)。
原型:char *fgets(char *str, int n, FILE *stream)

處理并傳遞參數(shù)
4.strtok:分解字符串 str 為一組字符串,delim 為分隔符。
原型:char *strtok(char *str, const char *delim)

5.putenv setenv getenv獲取設置環(huán)境變量相關函數(shù)
頭文件:#include4<stdlib.h>
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:分配所需的內(nèi)存空間,并返回一個指向它的指針。
原型: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)

轉(zhuǎn)載于:https://www.cnblogs.com/taoshihan/p/8313418.html

總結

以上是生活随笔為你收集整理的[PHP] 通用网关接口CGI 的运行原理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。