愛悠閑 > FCGI

FCGI

分類: 點滴積累  |  標簽: FCGI Demo  |  作者: seucbh84 相關  |  發布日期 : 2012-10-14  |  熱度 : 404°

fcgi作為客戶端需要注意的幾點

鏈接地址

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庫可以在鏈接地址頁面下載,希望對有這方面需求的同學們有所幫助

 

鏈接地址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;
}

 



快乐彩中奖说明