FCGI

来源:互联网 发布:二维平移矩阵 编辑:程序博客网 时间:2024/05/21 18:48

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;
}