Achieve a similar device configured as a router through the WEB page

Implementation to interact with other processes through the web

        To be like as a router, by visiting a Web page will be able to configure the device, essentially a web server communication problems with other processes. The key is, can notify another process when the server receives a request to our web browsers to deal with. Usually configure a device program can be used to achieve high-level or low-level language, but suffer when we do not know what the configuration or configurations, but only user interaction with a web page to know. As long as our web page can tell our configuration process parameters to be configured, then the problem is solved.

        The simplest is to achieve through the database, because web applications support database, upon receipt of a user request, the parameters to be configured so written to the database, and writes a flag, and our configuration process is triggered by a timer constantly read database, when the flag is found changed, then reads the configuration parameters for the corresponding configuration. This is the simplest kind of structure.

         Another is the web application through socket socket interaction with other processes. Socket socket and widely used cross-platform enough, as long as your web server code can support socket basically get away, like PHP, C # are all pretty good. Unfortunately, I am only a little c and c ++ .... try to find support c or c ++ approach. Sure enough, I found fastCGI. Official website is www.fastcgi.com. Which are described in detail and so on. fastCGI realize that white is actually a main function. In the main function, when there is no request on the obstruction, when there is a request, the function and then run, usually a cycle of constantly waiting for a request from the browser. For each request, the server and the client have a lot of information can be obtained by request of environmental variables, such as the request is a GET or POST and so on. The customer sent over the data (e.g. POST) to e.g. getchar () and the like obtained by standard stdin. As a response to the request how you can do with familiar c. Finally, return to the user's html code to output to a user via stdout. E.g. printf (), fprintf () and the like.

        Many network servers support fastCGI, I am using a linux apache server platform, all used in cross-platform support. Of course, apache server is too strong, if embedded devices such as routers or take a lightweight server better. apache server receives a request from a client browser browser, and then request to deal with turn-by-fastCGI process. fastCGI program supports multiple languages ​​such as perl, php, java, c, c ++, etc., since it can be implemented in C language, that means you can use the socket function in fastCGI do whatever they want inside, etc., etc., through the socket, the other will be able to fastCGI process communication process or on other machines.


Inux the apache server configuration, fastCGI module and fastCGI development kit

         Configuring apache server module fastCGI took me a few days, I have been trying to examples of fast-dev-kit inside the run, mostly configuration issues. Extracting httpd-2.2.19.tar.gz (apache_http server), mod_fcgid- 2.3.6 (apache_http fastcgi server module), fcgi-2.4.0 (fastCGI c or c ++ development package), there are also described readMe file. ./Configure first default in httpd-2.2.19 configuration. Then make, make install apache server installed. After the installation will appear in the / usr / local / apache2 directory under Start apache server in usr / local / apache / bin,. / Apachectl -k start. Enter localhost in your browser to see if apache server started successfully. Then install mod_fcgid-2.3.6, configure.apxs there in its directory file, the program needs to be configured by apxs apache2 / bin / under run APX = / usr / local / apache2 / bin / apxs ./configure.apxs fastCGI module is configured, then make, makeinstall installation. After the installation will be in the apache / modules / under more mod_fcgid.so document describing fastCGI module has been successfully installed. fastCGI development kit is also ./configure,make,make install installation.


FastCGI implement a program in C language:

程序如下:
#include "fcgi_stdio.h"
#include <stdlib.h>

   int main()
   {
       int count = 0;
       while(FCGI_Accept() >= 0)
           printf("Content-type: text/html\r\n"
                  "\r\n"
                  "<title>FastCGI Hello!</title>"
                  "<h1>FastCGI Hello!</h1>"
                  "Request number %d running on host <i>%s</i>\n",
                   ++count, getenv("SERVER_NAME"));

    return 0;
   }

        当用户有请求时,FCGI_Accept()就会返回。这里的printf是fcgi_stdio.h里的printf,printf的内容会返回给用户。程序的编译需要开发包下的/libfcgi/下的fcgi_stdio.c、 fcaiapp.c、和os_unix.c。用g++来编译。还要把开发包下的include文件加入路径。编译可能会报错因为socklen_t的问题。看了os_unix.c的源代码之后你就明白了,我为求方便加了个宏定义就编译通过了。生成程序tiny.fcg。
        接下来得配置apache服务器,使它可以运行我们的tiny.fcg程序。apache的服务器的配置都在/conf/下的httpd.conf文件里。
在里面添加如下信息:

LoadModule fcgid_module modules/mod_fcgid.so

<Directory "/usr/local/apache2/fcgi-bin">
    SetHandler fcgid-script
    AllowOverride None
    Options None
    Order allow,deny
    Allow from all
</Directory>


          大家注意了,我之所以花了几天时间fastCGI程序都跑不起来就是因为SetHandler项,我一直写了fcgi-script!!!少了一个d。我还重装了两遍apache..最后终于让我发现了。一改为fcgid-script。。终于可以了!当访问出错的时候,apache会把错误记录在apache/logs/下的error_log和access_log,当你调试fastCGI程序的时候,这两个文件给你很大帮助。

          apache的配置文件里的语法官网都有介绍,要是你配置了还跑不起来,你就得像我那样去啃官网的英文文档了看天意了。。。。
          配置好后fcgi-bin文件夹里面的程序收到请求时都自动调用fastCGI来跑。假设我们里面有tiny.fcg文件。那么访问localhost/fcgi-bin/tiny.fcg时,请求就交由tiny.fcg处理了。正如我们c语言实现那样网页返回以下内容:
FastCGI Hello!
Request number 1 running on host localhost
刷新几次之后,number会变化。

        整个过程,我们充当一个web服务器的角色,对于用户的请求,由我们来生成html页面,然后把html源码通过printf或其他stdout返回给用户。还得熟悉下html以及javascript脚本语言这程序才好写啊。



fastCGI如何获得用户GET或者POST过来的数据

有代码有真相:先贴再解释


#include "fcgi_config.h"
#include "fcgiapp.h"
#include <sys/types.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif


int main(void)
{

    int rc;

    FCGX_Init();
    pid_t pid = getpid();
    FCGX_Request request;
    char *server_name;

    FCGX_InitRequest(&request, 0, 0);

    for (;;)
    {
        rc = FCGX_Accept_r(&request);

        if (rc < 0)
            continue;

        char buffer[1024*10];
        buffer[0] = '\0';
        char** p = request.envp;
        while(*p)
        {
            strcat(buffer,*p);
            strcat(buffer,"\r\n");
            p++;
        }

        server_name = FCGX_GetParam("SERVER_NAME", request.envp);

        FCGX_FPrintF(request.out,
            "Content-type: text/html\r\n"
            "\r\n"
            "<title>FastCGI Hello!</title>"
            "<h1>FastCGI Hello! </h1>"
             "<p>Process %ld</p>"
            "<p> host<i>%s</i></p>"
            "the environments we get is: <p>"
            "<pre>%s</pre>",
            pid, server_name ? server_name : "?",buffer);


        //
        char* method = FCGX_GetParam("REQUEST_METHOD",request.envp);
        if(strcmp(method,"POST") == 0)
        {
            char postedData[1024*10];
            int dataNum = 0;
            int ch;
            while((ch = FCGX_GetChar(request.in)) != -1)
            {
                postedData[dataNum++] = (char)ch;
            }

            postedData[dataNum] = '\0';

            FCGX_FPrintF(request.out,
                         "<p>the data posted is:</p>"
                         "<pre>%s</pre>",postedData);
        }

        FCGX_Finish_r(&request);

    }
        return 0;
}


      基本上你看到函数名字大概就能猜到了,并且可以看源代码的。首先看以下 FCGX_Request的结构。


typedef struct FCGX_Request {
    int requestId;            /* valid if isBeginProcessed */
    int role;
    FCGX_Stream *in;
    FCGX_Stream *out;
    FCGX_Stream *err;
    char **envp;

    /* Don't use anything below here */

    struct Params *paramsPtr;
    int ipcFd;               /* < 0 means no connection */
    int isBeginProcessed;     /* FCGI_BEGIN_REQUEST seen */
    int keepConnection;       /* don't close ipcFd at end of request */
    int appStatus;
    int nWriters;             /* number of open writers (0..2) */
    int flags;
    int listen_sock;
} FCGX_Request;


       里面的in就是stdin,可以读取由浏览器POST过来的数据。out就是输出,往out printf的内容将返回给浏览器用户。envp就是字符串数组的指针,里面保存的都是环境变量,源代码就把这些环境变量都打印出来了。把fastCGI程序(我起名为learnFCGI)放入apache服务器的fcgi-bin文件夹(已配置好)。我在浏览器访问localhost/fcgi-bin/learnCGI得到以下内容


FastCGI Hello!

Process 12660

hostlocalhost

the environments we get is:FCGI_ROLE=RESPONDER

HTTP_HOST=localhost

HTTP_USER_AGENT=Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.6) Gecko/20100626 SUSE/3.6.6-1.2 Firefox/3.6.6

HTTP_ACCEPT=text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

HTTP_ACCEPT_LANGUAGE=en-us,en;q=0.5

HTTP_ACCEPT_ENCODING=gzip,deflate

HTTP_ACCEPT_CHARSET=ISO-8859-1,utf-8;q=0.7,*;q=0.7

HTTP_CONNECTION=close

PATH=/usr/lib64/mpi/gcc/openmpi/bin:/sbin:/usr/sbin:/usr/local/sbin:/root/bin:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/X11R6/bin:/usr/games:/usr/lib/mit/bin:/usr/lib/mit/sbin

SERVER_SIGNATURE=

SERVER_SOFTWARE=Apache/2.2.19 (Unix) mod_fcgid/2.3.6

SERVER_NAME=localhost

SERVER_ADDR=::1

SERVER_PORT=80

REMOTE_ADDR=::1

DOCUMENT_ROOT=/usr/local/apache2/htdocs

[email protected]

SCRIPT_FILENAME=/usr/local/apache2/fcgi-bin/learnFCGI

REMOTE_PORT=45762

GATEWAY_INTERFACE=CGI/1.1

SERVER_PROTOCOL=HTTP/1.1

REQUEST_METHOD=GET

QUERY_STRING=

REQUEST_URI=/fcgi-bin/learnFCGI

SCRIPT_NAME=/fcgi-bin/learnFCGI

       Since I am directly accessible, even REQUEST_METHOD as GET, QUERY_STRING is also empty, and no additional POST data, may wish to write down a simple HTML test page.

code show as below:

<html>
<body>
<form action="/fcgi-bin/learnFCGI" method="get">
    name:<input type="text" name="myName" ></br>
    passwrod:<input type="text" name="myPassword"></br>
    <input type="submit" value="提交">
</form>
</body>
</html>


         把html保存为testpage.html放在apache的usr/local/apache2/htdocs目录下。就能访问了,我这里通过localhost/testpage.html得到


         往文本框里输入testname,testpassword.按提交则会转到learnFCGI程序。我们会发现,这次打印的环境变量的QUERY_STRING发生了变化:


QUERY_STRING=myName=testname&myPassword=testpassword

我们的内容提交到fastCGI程序了。


把html代码里<form> 中的method属性改为 method="post",再次运行就能看到POST数据了


REQUEST_METHOD=POST

QUERY_STRING=

REQUEST_URI=/fcgi-bin/learnFCGI

SCRIPT_NAME=/fcgi-bin/learnFCGI


the data posted is:

myName=testname&myPassword=testpassword

        In use fastCGI process, not a lot of information online. . Basically, I went to the official website of the English eating, eating several times also are not a how writing. I had no choice but to try. . The most important thing is to write a small program to test. . FCGX_Request like environment variables inside what could have been, I do not know, then write a program to which are printed out. . Found that there are a REQUEST_METHOD and QUERY_STRING options, I know that you can submit data to fastCGI. And try to getchar () Verify that you can get POST data.


      Thus, by fastCGI, web programs will be able to submit data to another process to deal with.

Published 15 original articles · won praise 2 · views 50000 +

Guess you like

Origin blog.csdn.net/imhikaru/article/details/6700631