首页 » 技术分享 » FCGI

FCGI

 

fcgi作为客户端需要注意的几点

http://blog.csdn.net/cleanfield/article/details/6699952

fcgi作为中间层,需要与后端server通信进行数据处理,这里需要注意一下几点:

1.要做好超时处理,fcgi跟cgi不同,往往只有几个固定数量的进程,与server类似,因为如果一个fcgi进程挂住会导致整个fcgi逻辑层的处理能力下降N分之一(N为fcgi进程数)。这里的超时包括connect超时、send超时和recv超时

2.server对每一次fcgi请求都要有回包,在fcgi recv到回包后退出处理,关闭与server的连接

3.recv时要注意一定要recv到整个逻辑包(注意这里是整个逻辑包,即包头中标识的包头+包体的长度,收完这样一块buff才可以认为是recv完成)

4.注意mtu,1500,如果是通过poll来实现recv超时,一定要注意3中提到的recv全部逻辑意义上的完整包,因为对于大于mtu的包来说,肯定会大于一次发送,所以recv也必须大于一次

最新的socket库可以在http://download.csdn.net/source/3530843页面下载,希望对有这方面需求的同学们有所帮助

 

fcgi demo

#include <cstdlib>

#include <fcgio.h>

#define REQMAX 5242880

#define BUFSIZE 65536

using namespace std;

//得到环境变量

string safeGetEnv(const char* name,FCGX_Request * request){

    const char* ptr = FCGX_GetParam(name, request->envp);

    if(ptr == NULL){

        return "";

    }else{

        return string(ptr);

    }

}

//取得输入

long gstdin(FCGX_Request *request,string &reqstr,string &ip,string &cookie){

    long reqlength=-1,len=0,i;

    //得到IP地址

    ip = safeGetEnv("REMOTE_ADDR",request);

    if(ip==""){

        ip="0.0.0.0";

    }

    //得到cookie

    cookie = safeGetEnv("HTTP_COOKIE",request);

    //判断请求类型

    string reqmtd=safeGetEnv("REQUEST_METHOD",request);

    if(reqmtd=="POST"){

        string reqlen = safeGetEnv("CONTENT_LENGTH",request);

        char buffer[BUFSIZE+1];

        if(reqlen!=""){

            reqlength=strtoul(reqlen.c_str(), NULL, 10);

        }

        if(reqlength<=0){

            return -1; //错误

        }

        if(reqlength>REQMAX+1024){

            return -2; //请求忒长了

        }

        //读标准输入

        while(len<reqlength){

            cin.read(buffer,BUFSIZE);

            i=cin.gcount();

            if(i<=0){

                return -1; //错误

            }

            len+=i;

            reqstr.append(buffer,i);

        }

    }else{

        reqstr=safeGetEnv("QUERY_STRING",request);

        reqlength=reqstr.length();

    }

    return reqlength;

}

int main(int argc,char *argv[]){

    FCGX_Request request;

    FCGX_Init();

    FCGX_InitRequest(&request, 0, 0);

    while (FCGX_Accept_r(&request) == 0){

       
fcgi_streambuf cin_
fcgi_streambuf(request.in);

       
fcgi_streambuf cout_
fcgi_streambuf(request.out);

       
fcgi_streambuf cerr_
fcgi_streambuf(request.err);

        cin.rdbuf(&cin_
fcgi_streambuf);

        cout.rdbuf(&cout_
fcgi_streambuf);

        cerr.rdbuf(&cerr_
fcgi_streambuf);

       

        string reqstr="",ip="",cookie="";

        long reqlen=gstdin(&request,reqstr,ip,cookie);

        if(reqlen<0){

            continue;

        }

        cout<<"Content-Type: text/plain\r\n\r\n";

        cout<<"IP:["<<ip<<"]\n";

        cout<<"Cookie:["<<cookie<<"]\n";

        cout<<"REQUEST:\n"<<reqstr<<endl;

    }

    return 0;

}

转载自原文链接, 如需删除请联系管理员。

原文链接:FCGI,转载请注明来源!

2