目录

一、简介fcgi:web和web服务器间数据传输的桥梁... 2

二、源码编译配置ARM Lighttpd Fastcgi C.. 3

【1】交叉编译。源文件都从官网下载。 Fcgi lighttpd  zlib. 3

【2】配置服务器server.document-root="/www" fastcgi.server "bin-path" => "/www/fastcgi.fcgi", 4

【3】fastcgi编程程序  将生成的文件拷贝到设备/www目录中... 4

【4】启动服务器... 6

【5】测试... 6

三、fastcgi编程实例... 7

多线程请求例子... 7

四、fcgiapp各个数据结构和函数含义... 9

FCGX_Stream该struct定义了FastCGI流的状态。... 9

FCGX_Request对一个请求的封装。可供访问的属性:... 9

int FCGX_Init()  Initialize the FCGX library. 10

int FCGX_InitRequest(FCGX_Request *request, int sock, int flags). 10

int FCGX_Accept_r(FCGX_Request *request) 接受一个新的请求(多线程安全)。... 10

int FCGX_PutChar(int c, FCGX_Stream *stream)  将字符c写入stream。... 10

int FCGX_PutStr(const char *str, int n, FCGX_Stream *stream)  用于二进制输出。... 11

int FCGX_PutS(const char *str, FCGX_Stream *stream)  用于输出字符串。... 11

int FCGX_FPrintF(FCGX_Stream *stream, const char *format, ...) 将格式化字符串format写入stream。     11

int FCGX_GetChar(FCGX_Stream *stream) 从输入读取一个字节。... 11

int FCGX_UnGetChar(int c, FCGX_Stream *stream) 将字符c推回输入流stream。... 11

int FCGX_GetStr(char *str, int n, FCGX_Stream *stream) 从stream中读取n个连续字节到str中。     12

char *FCGX_GetLine(char *str, int n, FCGX_Stream *stream) 从stream中读取n-1个连续字节到str中。     12

int FCGX_HasSeenEOF(FCGX_Stream *stream) 在读取stream时,如果检测到EOF,那么返回EOF,否则返回0。     12

五、Lighttpd 网页服务源码分析说明post数据lighttpd主程序不处理,而是交给动态执行模块fastcgi等来解析。     12

六、参考... 15

lighttpd fastcgi的搭建... 15

fastcgi 分布式... 15

fcgiapp各个数据结构和函数含义... 15

FastCGI编程介绍... 15

在FastCGI应用程序中无法获取HTTP POST的主体... 16

一、简介fcgi:web和web服务器间数据传输的桥梁

FastCGI就像CGI一样,FastCGI也是独立于编程语言的。

是web和web服务器间数据传输的桥梁。

就像CGI一样,FastCGI程序运行在完全独立于核心Web Server之外的进程中,

Fastcgi的缺点:

1、对某些服务器的新版本支持不好,对分布式负载均衡没要求的模块化安装是否是更好的选择。

2、目前的fastcgi和server沟通还不够智能,一个fastcgi进程如果执行时间过长会被当成是死进程杀掉重起,这样在处理长时间任务的时候很麻烦.这样做也使得fastcgi无法允许联机调试。

lighttpd提供了一种外部程序调用的接口,即FastCGI接口。这是一种独立于平台和服务器的接口,它介于Web应用程序和Web服务器之间。

FastCGI工作方式是接受Web服务器的请求,以HTTP Request的方式进行响应,实现了应用程序与Web服务器的分离。它的使用需要在Web服务器中安装支持组件,目前支持Apache、Nginx、IIS、Lighttpd等。

优点有:

  • 稳定性fastcgi是以独立的进程池运行来cgi单独一个进程死掉,系统可以很轻易的丢弃,然后重新分配新的进程来运行逻辑
  • 安全性,fastcgi和宿主的server完全独立,fastcgi怎么down也不会把server搞垮
  • 性能, fastcgi把动态逻辑的处理从server中分离出来, 大负荷的IO处理还是留给宿主server, 这样宿主server可以一心一意作IO,对于一个普通的动态网页来说,,逻辑处理可能只有一小部分,大量的图片等静态IO处理完全不需要逻辑程序的参与
  • 扩展性,fastcgi是一个中立的技术标准,完全可以支持任何语言写的处理程序(php、java、python、C++)

FastCGI编程包括四部分:初始化编码、接收请求循环、响应内容、响应结束循环。

CGI能够使用C语言编写,以通过共享内存等方式与其他C语言进程通讯。对CGI程序的每个HTTP请求,web服务器都会创建一个新的CGI进程,web服务器通过环境变量传递http请求,CGI程序通过标准输出返回处理结果,然后退出。

fastcgi使用循环响应HTTP请求,服务器负载比cgi小,能与其他程序(如数据库)保持持续链接。fastcgi可以使用tcp或UNIX domain与web服务器通讯,并将HTTP请求转换为环境变量传入,TCP方式中使用标准输出返回处理结果,UNIX domain方式则使用fastcgi封装的函数。cgi-fcgi程序能够将cgi程序作为fastcgi程序运行。

lighttpd支持fastcgi,能够启动fastcgi程序,并进行负载均衡。

二、源码编译配置ARM Lighttpd Fastcgi C

【1】交叉编译。源文件都从官网下载。 Fcgi lighttpd  zlib

http://download.lighttpd.net/lighttpd/releases-1.4.x/lighttpd-1.4.33.tar.bz2

http://www.fastcgi.com/dist/fcgi.tar.gz

http://zlib.net/zlib-1.2.8.tar.gz

tar xf zlib-1.2.8.tar.gz                                
cd zlib-1.2.8                                            
CC=arm-linux-gcc ./configure --prefix=/home/armroot
make                                                    
make install
tar xf fcgi.tar.gz
cd fcgi-2.4.1-SNAP-0311112127/
./configure --host=arm-linux --prefix=/home/armroot
make
make install
tar xf lighttpd-1.4.33.tar.bz2 
cd lighttpd-1.4.33
 ./configure --host=arm-linux --prefix=/home/armroot --without-bzip2 --without-pcre
make
make install

拷贝可执行文件(这里是/home/armroot/sbin/lighttpd) 到设备中(我放在了/usr/local/bin/下)。

拷贝lighttpd的mod(这里是/home/armroot/lib/mod*.so)到设备中(我放在了/opt/lighttpd下)

【2】配置服务器server.document-root="/www" fastcgi.server "bin-path" => "/www/fastcgi.fcgi",

/etc/lighttpd.conf

server.document-root="/www"
server.port=80
mimetype.assign=(
    ".html" => "text/html",
    ".json" => "text/plain",
    ".css" => "text/css"
)
server.modules = ("mod_fastcgi",                                                  "mod_compress",                                                 
                )                                                                                
server.errorlog            = "/tmp/lighttpd/error.log"                          
server.indexfiles           = ("index.html")                                                                      
                                                                                
compress.cache-dir = "/tmp/lighttpd/cache/"                                     
compress.filetype = ("text/plain","text/html","text/css","text/javascript")                                                                                                                    
                                                                                
fastcgi.debug=0                                                                 
fastcgi.server = (                                                              
            ".fcgi" =>                                                          
            (                                                                   
                "main" =>                                                       
                (                                                               
                    "host" => "127.0.0.1",                                      
                    "port" => 2048,                                             
                    "bin-path" => "/www/fastcgi.fcgi",                          
                    "max-procs" => 1,                                           
                )                                                               
            )                                                                   
        )

【3】fastcgi编程程序  将生成的文件拷贝到设备/www目录中

test.c

#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcgi_stdio.h>
int count = 0;
int main()
{
    while(FCGI_Accept() >= 0)
    {
        int width = 0;
        int height = 0;
        char *query_string = getenv("QUERY_STRING");
        if(query_string != NULL)
            sscanf(query_string, "width=%d&height=%d", &width, &height);printf("Content type: text/html\n\n");
        printf("width=%d,height=%d\n",width,height);
        printf("pid=%d\n",getpid());
        printf("count=%d\n",count);
        count++;
    }
    return 0;
}
 

Makefile:

CROSS_PREFIX=arm-linux-CC=$(CROSS_PREFIX)gccSTRIP=$(CROSS_PREFIX)stripARMROOT=/home/armrootLIB=$(ARMROOT)/libINC=$(ARMROOT)/includeCFLAGS= -g -I$(INC) --std=gnu99 -W -Wall -O0SRC=$(shell find ./ -name '*.c')OBJ=$(SRC:%.c=%.o)DEP=$(SRC:%.c=%.dep)#LIBS:动态库LIBS=-lpthread -lfcgi -lz#SLIBS:静态库SLIBS=TARGET=fastcgi$(TARGET): $(DEP) $(OBJ)@echo -n linking...@$(CC) $(SLIBS) $(OBJ) -o $(TARGET) $(CFLAGS) -L$(LIB) $(LIBS)@echo done: $(TARGET).PHONY:stripstrip:$(TARGET)@if [ -e $(TARGET)_g ];then rm $(TARGET)_g;fi@cp $(TARGET) $(TARGET)_g@$(STRIP) $(TARGET)%.dep:%.c@$(CC) -MM $< $(CFLAGS) > $@__@if [ -e $@__ ];then echo -n $(dir $@) > $@;cat $@__ >> $@;rm $@__;fisinclude $(DEP)%.o:%.c@echo building $<@$(CC) -c $< -o $@ $(CFLAGS).PHONY:cleanclean:@for i in $(DEP);do if [ -e $${i} ];then rm $${i};fi;done@for i in $(OBJ);do if [ -e $${i} ];then rm $${i};fi;done@if [ -e $(TARGET) ];then rm $(TARGET);fi

将生成的文件拷贝到设备/www目录中

【4】启动服务器

lighttpd -f /etc/lighttpd.conf 

-f 选项指定配置文件

-m 选项指定mod所在目录,默认为编译lighttpd时的prefix/lib,我这里就是/home/armroot/lib。

lighttpd会在初始化时启动配置文件中指定的fastcgi程序,这里是/www/fastcgi.fcgi

【5】测试

ps

523 root       0:00 lighttpd -f /etc/lighttpd.conf  -m /opt/lighttpd           
542 root       0:00 /www/fastcgi.fcgi

浏览器访问

http://192.168.1.127/fastcgi.fcgi?width=800&height=480

结果:

width=800,height=480 
pid=542 
count=0
width=800,height=480 
pid=542 
count=1

三、fastcgi编程实例

多线程请求例子

#include <string.h>

#include <syslog.h>

#include <alloca.h>

#include <fcgiapp.h>

#include <stdio.h>

#include <string>

#include <sstream>

#define THREAD_COUNT 20

#define LISTENSOCK_FILENO 0

#define LISTENSOCK_FLAGS 0

static int counts[THREAD_COUNT];

static void *doit(void *a)

{

int rc;

FCGX_Request request;

int err = FCGX_InitRequest(&request, LISTENSOCK_FILENO, LISTENSOCK_FLAGS);

if (err) { syslog(LOG_INFO, "FCGX_InitRequest failed: %d", err); return ; }

int count = 0;

    for (;;) 

{

rc = FCGX_Accept_r(&request);

if (rc < 0)

break;

FCGX_FPrintF(request.out,

"Content-type: text/html\r\n"

"\r\n"

"<title>FastCGI Hello! ");

// 输出计数

FCGX_FPrintF(request.out, "<p>Count:%d</p>", ++count);

// 输出数据长度

char *len = FCGX_GetParam("CONTENT_LENGTH", request.envp);

FCGX_FPrintF(request.out, "<p>Data length:%s\n</p>", (len ? len : "0"));

// 环境变量

auto envp = request.envp;

std::ostringstream output;

output << "<PRE>\n";

for (; *envp; ++envp)

{

output << *envp <<"\n";

}

output << "</PRE>\n";

// 输出

FCGX_PutS(output.str().c_str(), request.out);

// 获取body中数据,然后输出

if (len)

{

long length = -1;

try {

length = std::stol(len);

} catch (...){}

if (length > 0)

{

std::string data(length, '\0');

int size = FCGX_GetStr((char *)data.data(), length, request.in);

FCGX_FPrintF(request.out, "<p>read data size:%d</p>", size);

FCGX_PutStr(data.data(), data.size(), request.out);

}

}

sleep(2);

FCGX_Finish_r(&request);

}

return NULL;

}

int main(void)

{

int i;

pthread_t id[THREAD_COUNT];

int err = FCGX_Init(); /* call before Accept in multithreaded apps */

if (err) { syslog (LOG_INFO, "FCGX_Init failed: %d", err); return 1; }

for (i = 1; i < THREAD_COUNT; i++)

pthread_create(&id[i], NULL, doit, (void*)i);

doit(0);

return 0;

}

四、fcgiapp各个数据结构和函数含义

FCGX_Stream该struct定义了FastCGI流的状态。

流的状态是私有的,只能通过下面定义的程序访问。

FCGX_Request对一个请求的封装。可供访问的属性:

int requestId       // 是否线程独立?
int role;
FCGX_Stream *in;    // 在post方法中用来读取数据?
FCGX_Stream *out;      // 输出应答内容
FCGX_Stream *err;
char **envp;       // 系统 + Request的环境变量

int FCGX_Init()  Initialize the FCGX library. 

Call in multi-threaded apps before calling FCGX_Accept_r().
Returns 0 upon success.

int FCGX_InitRequest(FCGX_Request *request, int sock, int flags)

Initialize a FCGX_Request for use with FCGX_Accept_r().
参数sock是0(默认)或者是FCGX_OpenSocket()的返回值。
参数flags当前只支持FCGI_FAIL_ON_INTR(实现中并没有定义,都是使用0)。

int FCGX_Accept_r(FCGX_Request *request) 接受一个新的请求(多线程安全)。

一定要先调用一次FCGX_Init()。
成功放回0,失败返回-1。

结束request(并释放上一次调用中申请的内存)。创建输入,输出,错误流,
并分别赋值给(request中的)*in,*out,*err。创建包含参数的数据结构,并赋值给*envp
可以通过getenv(如果将数据赋值给了environ)或FCGX_GetParam来访问。

不要一直保留指向envp数组或其中字符串的指针(例如FCGX_GetParam返回的结果),
因为在下一次调用FCGX_Finish或FCGX_Accept之后,它们都会被freed。

不要直接使用FCGX_Request,他的结构可能改变。

int FCGX_PutChar(int c, FCGX_Stream *stream)  将字符c写入stream。

成功返回c,失败返回EOF(-1)。

int FCGX_PutStr(const char *str, int n, FCGX_Stream *stream)  用于二进制输出。

从str开始,向stream中写入n个连续字节。对输出字节不做任何解释。
用于二进制输出。
成功返回写入的字节数,失败放回EOF(-1)。

int FCGX_PutS(const char *str, FCGX_Stream *stream)  用于输出字符串。

将已null结尾的字符串str写入stream,由FCGX_PutStr实现。
用于输出字符串。
成功返回写入的字节数,失败放回EOF(-1)

int FCGX_FPrintF(FCGX_Stream *stream, const char *format, ...) 将格式化字符串format写入stream。

成功返回写入的字节数,失败放回EOF(-1)

int FCGX_GetChar(FCGX_Stream *stream) 从输入读取一个字节。

返回读取的字节,如果到达输入结尾,则返回EOF(-1).

int FCGX_UnGetChar(int c, FCGX_Stream *stream) 将字符c推回输入流stream。

读取一个字符后再推回一个字符是确保可以实现的。
到达EOF后不能再执行推回操作。
如果成功返回c,否则返回EOF。

int FCGX_GetStr(char *str, int n, FCGX_Stream *stream) 从stream中读取n个连续字节到str中。

对读入字节不做任何解释。
返回读取的字节数,如果返回值小于n,说明已达到结尾。

char *FCGX_GetLine(char *str, int n, FCGX_Stream *stream) 从stream中读取n-1个连续字节到str中。

在读取n-1个字节前,如果碰到'\n'或EOF则停止,
结尾的‘\n’会被复制到str中。当复制完最后一个字节后,在str最后添加字节‘\0’。
如果读取的第一个字节就是EOF,那么返回NULL,否则返回str。

int FCGX_HasSeenEOF(FCGX_Stream *stream) 在读取stream时,如果检测到EOF,那么返回EOF,否则返回0。

请注意,FCGX_HasSeenEOF(s)可能会返回0,然后立即调用FCGX_GetChar(s)可能会返回EOF。
这个功能就像C函数feof,没有提供peek ahead功能。

五、Lighttpd 网页服务源码分析说明post数据lighttpd主程序不处理,而是交给动态执行模块fastcgi等来解析。


lighttpd处理静态页面要使用mod_staticfile.c插件。是lighttpd默认会加载的。

工作路径:server.document-root

如果需要配置fcgi,一般在modules.conf中使能include conf.di.conf比较合理。

六、参考

lighttpd fastcgi的搭建

https://www.cnblogs.com/fellow1988/p/6135756.html?utm_source=itdadao&utm_medium=referral

fastcgi 分布式

https://www.cnblogs.com/fellow1988/p/6139459.html

fcgiapp各个数据结构和函数含义

https://my.oschina.net/u/4274876/blog/3927213

FastCGI编程介绍

https://blog.csdn.net/lee244868149/article/details/45099723

在FastCGI应用程序中无法获取HTTP POST的主体

http://www.cocoachina.com/articles/109191

从HTML格式成功发布1MB文件,并且变量“ CONTENT_LENGTH”足够大:)但我不知道如何使用libfcgi访问POST请求的主体.这是我的HTML表单,效果很好.

<form action="/upload" enctype="multipart/form-data" method="POST">

<input type="test" name="text1" />

<input type="file" name="file1" />

<input type="submit" />

</form>

通过接受请求

int FCGX_Accept_r(FCGX_Request *request);

在 FCGX_Request 内部,我们有3个流:in,out,err. “ in”流中的标志为isReader == 1,其他的isReader == 0.

FCGX_Stream

该struct定义了FastCGI流的状态。流的状态是私有的,只能通过下面定义的程序访问。

FCGX_Request

对一个请求的封装。可供访问的属性:

int requestId       // 是否线程独立?

int role;

FCGX_Stream *in;    // 在post方法中用来读取数据?

FCGX_Stream *out;      // 输出应答内容

FCGX_Stream *err;

char **envp;       // 系统 + Request的环境变量

最佳答案

libfcgi提供了从输入流中读取的三个函数 FCGX_GetStr,FCGX_GetLine 和 FCGX_GetChar.

while (FCGX_GetStr(buf, sizeof(buf), request.in) > 0) {

/* ... */

}

您将需要解析 multipart/form-data 主体.

官网多线程的例子,(http://www.fastcgi.com/devkit/examples/threaded.c)

web服务选择lighttpd,采用fcgi组件技术扩展处理业务层相关推荐

  1. Web服务生存周期内发生的事件/Soap扩展的阶段/Soap扩展的步骤

    客户端创建WEB服务代理类的一个新实例,该对象驻留在客户端所在的同一台计算机上. 客户端调用代理类上的方法. 客户端计算机上的ASP.NET框架的基础结构将WEB服务方法的参数序列化为SOAP消息,并 ...

  2. cookie和session、web服务工作原理、Apache配置php扩展、php简介

    cookie和session: cookie和session区别:cookie数据是存在本地的,而session数据是存在服务端的,session比cookie更安全. cookie:用于http做会 ...

  3. Web服务集成CRM的应用

    本文讲的是Web服务集成CRM的应用,[IT168 资讯]近年来,很多企业应用集成(EAI)供应商都提供专有的适配器和集成服务器工具集,试图解决企业应用集成过程中面临的挑战.虽然EAI解决方案很有效, ...

  4. 基于使用学习排序算法的Web服务学习的个性化的决策战略

    摘要----为了从类似的服务列表中进行功能上的选择,用户往往需要根据多个QoS准则做出他们的决定,它们需要对目标服务.在这个过程中,不同的用户可能遵循不同的决策策略,有些是补偿性的,在这个补偿中在所有 ...

  5. IBM Lotus Domino 7 中的实用 Web 服务,第 1 部分: 什么是 Web 服务以及它们为何如此重要

    Julian Robichaux, 开发人员, 独立顾问 Julian Robichaux 是专门研究 IBM Lotus Notes 和 Java 开发的软件开发人员和专业程序员.他擅长于各种与开发 ...

  6. IBM Lotus Domino 7 中的实用 Web 服务,第 1 部分: 什么是 Web 服务以及它们为何如此重要...

    IBM Lotus Domino 7 中的实用 Web 服务,第 1 部分: 什么是 Web 服务以及它们为何如此重要 级别: 初级 Julian Robichaux, 开发人员, 独立顾问 2005 ...

  7. 一文讲透推荐系统提供web服务的2种方式

    作者丨gongyouliu 编辑丨zandy 来源 | 大数据与人工智能(ID: ai-big-data) 推荐系统是一种信息过滤技术,通过从用户行为中挖掘用户兴趣偏好,为用户提供个性化的信息,减少用 ...

  8. 中国人工智能学会通讯——机器人组件技术在智能制造系统中的应用

    摘要:随着工业4.0时代的到来,如何将传统工厂改造成为个性化.网络化.柔性生产的智能制造系统成为了当前的研究热点.本文从智能制造系统和智能机器人系统的相似性出发,构建了基于机器人组件技术的智能制造系统 ...

  9. Web服务安全性和SOA路线图的人为维度

    在大多数非平凡的SOA环境中,很难跟踪系统之间不断发展的集成,除非有明确的发布和查找适当信息的方法. 概述IT环境,定义当前或将要连接的内容,是维护环境的先决条件. 缺少这种情况通常会导致" ...

最新文章

  1. 设计一个成绩分类 输入成绩 输出优秀_BenQ 明基 PD2720U 27寸 Thunderbolt3.0 专业设计显示器开箱评测...
  2. 使用sql server中的全文索引
  3. 三菱modbusRTU通讯实例_实例 | 三菱PLC接线图干货,FX5U模块硬件
  4. 【计算机组成原理】指令格式
  5. c++ primer plus中文版_如何成为一名厉害的C/C++程序员?
  6. 基于CUDA的TTI介质逆时偏移与ADCIGs提取
  7. java多条件不定条件查询
  8. vue 组件模板template定义时的注意事项
  9. Firefox-常用扩展
  10. 客户端压测server端计算qps以及不同延迟时间下响应数量所占百分比
  11. 【直观理解】粒子滤波 原理及实现
  12. “”和“”的你真的理解吗?
  13. C++ 使用正则表达式拆分字符串
  14. 深入理解Azure自动扩展集VMSS(3)
  15. Flutter监听网络变化
  16. atitit.软件开发--socket框架选型--netty vs mina j
  17. 【机器学习】金融风控评分卡建模全流程!
  18. BUUCTF——MISC(流量分析)
  19. 清华大学2001年机试-字符串排序-1066
  20. 【前辈经验】——前端职位描述

热门文章

  1. 中职计算机应用基础笔记,计算机应用基础_自考笔记+自考资料.doc
  2. python数字推盘游戏怎么显示步数_Python游戏开发:数字华容道
  3. 在线jsp版泰囧表情的生成器代码,不用PS也能恶搞。
  4. Inno Setup 语法
  5. 高级软件工程--平时作业汇总
  6. 第一次来学习开料软件的使用
  7. Lighting System Design UVA - 11400 照明系统设计 线性结构dp
  8. 竞品分析该如何写?竞品分析的维度有哪些?
  9. 『TinyOS』 nesC 1.1 语言参考手册
  10. linux remount命令详解,linux mount命令参数及用法详解