zoukankan      html  css  js  c++  java
  • 嵌入式web服务器

    要实现在PC上通过网页控制连接到嵌入式开发板的相机。

    限于开发板的环境,不能选择appche等大型web服务器,选择了boa。

    要想pc端跨平台,那就不能用ActiveX控件,如果仅在windows平台上是可以的,使用这种方法,PC端要装插件。

    所以我选择纯html页面。

    如果仅仅是显示静态内容,那么直接把html页面放到boa的根目录下即可,但如果要创建动态页面,那就得使用cgi接口。

    在嵌入式上运行的web服务器基本也都只支持cgi接口,不支持什么asp,jsp。

    cgi是通用网关接口的意思,只是接口而已,能使用任何能实现输入输出的语言进行编程实现,web服务器对输入输出进行了重定向

    web服务器把从网页得到的输入全部重定向输出到cgi-bin目录的cgi程序作为输入,而cgi程序的输出重定向到web服务器,通过web服务器发送到浏览器。

    在嵌入式环境里现成的编程语言就是shell,c/c++,这是肯定支持的,php,python,perl也是可以支持的,但脚本语言要执行,那肯定得另外配置环境,

    如同java要运行需要jre一样。

    在这里,web服务器程序不仅要进行显示,还要控制相机,要跟相机控制程序进行通信,所以用shell不太现实,所以还是选择c语言。

    用c语言首先要有两类个基本的函数要实现,一是从网页发送过来的数据中提取传递的参数,二是读写配置文件。这是在没有加入通讯功能的阶段。

    借鉴别人的代码,首先是提取网页参数

    头文件:

    /* cgivars.h */

    #ifndef _CGIVARS_H
    #define _CGIVARS_H

    /* method */
    #define GET 0
    #define POST 1


    /* function prototypes */
    int getRequestMethod();
    char **getGETvars();
    char **getPOSTvars();
    int cleanUp(int form_method, char **getvars, char **postvars);

    void adminCheck();


    #endif /* !_CGIVARS_H */

    源文件:

    /* cgivars.c
    * (C) Copyright 2000, Moreton Bay (http://www.moretonbay.com).
    * see HTTP (www.w3.org) and RFC
    */

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>

    #include "cgivars.h"

    /* local function prototypes */
    char hex2char(char *hex);
    void unescape_url(char *url);
    char x2c(char *what);

    /* hex2char */
    /* RFC */
    char hex2char(char *hex) {
    char char_value;
    char_value = (hex[0] >= 'A' ? ((hex[0] & 0xdf) - 'A') + 10 : (hex[0] - '0'));
    char_value *= 16;
    char_value += (hex[1] >= 'A' ? ((hex[1] & 0xdf) - 'A') + 10 : (hex[1] - '0'));
    return char_value;
    }

    /* unescape_url */
    /* RFC */
    void unescape_url(char *url) {
    int n, k;
    for(n=0, k=0;url[k];++n, ++k) {
    if((url[n] = url[k]) == '%') {
    url[n] = hex2char(&url[k+1]);
    k += 2;
    }
    }
    url[n] = '';
    }


    /* getRequestMethod
    * retn: from_method (GET or POST) on success,
    * -1 on failure. */
    int getRequestMethod() {
    char *request_method;
    int form_method;

    request_method = getenv("REQUEST_METHOD");
    if(request_method == NULL)
    return -1;

    if (!strcmp(request_method, "GET") || !strcmp(request_method, "HEAD") ) {
    form_method = GET;
    } else if (!strcmp(request_method, "POST")) {
    form_method = POST;
    } else {
    /* wtf was it then?!! */
    return -1;
    }
    return form_method;
    }


    /* getGETvars
    * retn: getvars */
    char **getGETvars() {
    int i;
    char **getvars;
    char *getinput;
    char **pairlist;
    int paircount = 0;
    char *nvpair;
    char *eqpos;

    getinput = getenv("QUERY_STRING");
    if (getinput)
    getinput = strdup(getinput);

    //DEBUGMSG(1, ("gin=%s ", getinput));

    /* Change all plusses back to spaces */
    for(i=0; getinput && getinput[i]; i++)
    if(getinput[i] == '+')
    getinput[i] = ' ';

    pairlist = (char **) malloc(256*sizeof(char **));
    paircount = 0;
    nvpair = getinput ? strtok(getinput, "&") : NULL;
    while (nvpair) {
    pairlist[paircount++]= strdup(nvpair);
    if(!(paircount%256))
    pairlist = (char **) realloc(pairlist,(paircount+256)*sizeof(char **));
    nvpair = strtok(NULL, "&");
    }

    pairlist[paircount] = 0;
    getvars = (char **) malloc((paircount*2+1)*sizeof(char **));
    for (i= 0; i<paircount; i++) {
    if(eqpos=strchr(pairlist[i], '=')) {
    *eqpos = '';
    unescape_url(getvars[i*2+1] = strdup(eqpos+1));
    } else {
    unescape_url(getvars[i*2+1] = strdup(""));
    }
    unescape_url(getvars[i*2] = strdup(pairlist[i]));
    }
    getvars[paircount*2] = 0;
    for(i=0;pairlist[i];i++)
    free(pairlist[i]);
    free(pairlist);
    if (getinput)
    free(getinput);
    return getvars;
    }


    /* getPOSTvars
    * retn: postvars */
    char **getPOSTvars() {
    int i;
    int content_length;
    char **postvars;
    char *postinput;
    char **pairlist;
    int paircount = 0;
    char *nvpair;
    char *eqpos;

    postinput = getenv("CONTENT_LENGTH");
    if (!postinput)
    exit(1);
    if(!(content_length = atoi(postinput)))
    exit(1);
    if(!(postinput = (char *) malloc(content_length+1)))
    exit(1);
    if (!fread(postinput, content_length, 1, stdin))
    exit(1);
    postinput[content_length] = '';

    //DEBUGMSG(1, ("pin=%s ", postinput));

    for(i=0;postinput[i];i++)
    if(postinput[i] == '+')
    postinput[i] = ' ';

    pairlist = (char **) malloc(256*sizeof(char **));
    paircount = 0;
    nvpair = strtok(postinput, "&");
    while (nvpair) {
    pairlist[paircount++] = strdup(nvpair);
    if(!(paircount%256))
    pairlist = (char **) realloc(pairlist, (paircount+256)*sizeof(char **));
    nvpair = strtok(NULL, "&");
    }

    pairlist[paircount] = 0;
    postvars = (char **) malloc((paircount*2+1)*sizeof(char **));
    for(i = 0;i<paircount;i++) {
    if(eqpos = strchr(pairlist[i], '=')) {
    *eqpos= '';
    unescape_url(postvars[i*2+1] = strdup(eqpos+1));
    } else {
    unescape_url(postvars[i*2+1] = strdup(""));
    }
    unescape_url(postvars[i*2]= strdup(pairlist[i]));
    }
    postvars[paircount*2] = 0;

    for(i=0;pairlist[i];i++)
    free(pairlist[i]);
    free(pairlist);
    free(postinput);

    return postvars;
    }

    /* cleanUp
    * free the mallocs */
    int cleanUp(int form_method, char **getvars, char **postvars) {
    int i;

    if (postvars) {
    for(i=0;postvars[i];i++)
    free(postvars[i]);
    free(postvars);
    }
    if (getvars) {
    for(i=0;getvars[i];i++)
    free(getvars[i]);
    free(getvars);
    }

    return 0;
    }


    void adminCheck(){
    char * userName = NULL;
    char * errPage = "Location: UnauthorizedError.htm ";

    userName = getenv("REMOTE_USER");

    if(userName == NULL) goto err;

    if(!strcmp("admin",userName))
    {
    return;
    }


    err: printf("%s ",errPage);

    fflush(stdout);
    exit(0);
    }

    读取配置文件借鉴别人的,别人的读取是从配置文件读取,而写配置则只是写进一个临时文件,写进配置文件是由实际控制相机的服务程序实现的。

    我要将它改为直接将参数写进配置文件。

    头文件:

    #include <stdio.h>
    #define MAX_LINE_LENGTH 128
    struct item{
    char *session;
    char *key;
    char *value;};
    int get_value(char *filename,const char *session,const char *key,char *value);
    int set_value(char *filename,const char *session,const char *key,char *value);

     源文件:

    #include "parseini.h"
    #include <string.h>
    int get_value(char *filename,const char *session,const char *key,char *value)
    {
    int i,j;
    FILE *fp;
    char temp_line[128];
    char fake_session[128], fake_key[128];
    memset(temp_line, 0, MAX_LINE_LENGTH);
    fp=fopen(filename,"r+");
    while(fgets(temp_line, MAX_LINE_LENGTH, fp))
    {
    if(temp_line[0]=='[')
    {
    if(strstr(temp_line,session))
    {
    i=1; //no [
    while(temp_line[i]!=']')
    {
    fake_session[i-1]=temp_line[i];
    i++;
    }
    fake_session[i-1]=0;
    if(!strcmp(fake_session,session))
    {
    memset(temp_line, 0, MAX_LINE_LENGTH);
    do{
    fgets(temp_line, MAX_LINE_LENGTH, fp);
    if(temp_line[0]=='[')break;
    if((temp_line[0]!=';')&&strstr(temp_line,key))
    {
    i=0;
    while(temp_line[i]!='=')
    {
    fake_key[i]=temp_line[i];
    i++;
    }
    fake_key[i]=0;
    if(!strcmp(fake_key,key))
    {
    j=0;
    i++;
    while(temp_line[i]!=' ')
    {
    value[j]=temp_line[i];
    i++;
    j++;
    }
    value[j]=0;
    fclose(fp);
    return 1;
    }

    }
    }while(1);
    fclose(fp);
    return 0;
    }
    }
    }
    }
    fclose(fp);
    return 0;
    }
    int set_value(char *filename,const char *session,const char *key,char *value)
    {
    FILE *fp,*temp_fp;
    int i,j;
    char temp_line[128];
    char temp_file_name[]="/etc/temp_config.ini";
    char fake_session[128], fake_key[128];
    memset(temp_line, 0, MAX_LINE_LENGTH);
    fp=fopen(filename,"rb");
    temp_fp=fopen(temp_file_name,"w");
    while(fgets(temp_line, MAX_LINE_LENGTH, fp))
    {
    if(temp_line[0]=='[')
    {
    if(strstr(temp_line,session))
    {
    i=1; //no [
    while(temp_line[i]!=']')
    {
    fake_session[i-1]=temp_line[i];
    i++;
    }
    fake_session[i-1]=0;
    if(!strcmp(fake_session,session))
    {
    fputs(temp_line,temp_fp);
    memset(temp_line, 0, MAX_LINE_LENGTH);
    out: while(fgets(temp_line, MAX_LINE_LENGTH, fp))
    {
    if(temp_line[0]=='[')break;
    if((temp_line[0]!=';')&&strstr(temp_line,key))
    {
    i=0;
    while(temp_line[i]!='=')
    {
    fake_key[i]=temp_line[i];
    i++;
    }
    fake_key[i]=0;
    if(!strcmp(fake_key,key))
    {
    j=0;
    i++;
    while(value[j]!=0)
    {
    temp_line[i]=value[j];
    i++;
    j++;
    }
    temp_line[i]=' ';

    i++;
    while(temp_line[i]!=0)
    {
    temp_line[i]=0;
    i++;
    }

    fputs(temp_line,temp_fp);
    memset(temp_line, 0, MAX_LINE_LENGTH);
    goto out;
    }
    }
    fputs(temp_line,temp_fp);
    }
    }
    }
    }
    fputs(temp_line,temp_fp);
    memset(temp_line, 0, MAX_LINE_LENGTH);
    }
    fclose(fp);
    fclose(temp_fp);
    unlink(filename);
    rename(temp_file_name,filename);
    return 0;
    }

  • 相关阅读:
    ftp 传文件完整代码(二)
    生成文件 权限 以及ftp 传数据(一)
    定时任务配置
    发送电子邮件遇到问题
    mysql 主从分离配置
    知道开始时间结束时间 计算这之间一共多少天
    mysql 语句集(二)
    mysql 的sql文件导出导入
    mysql 批量添加 更新
    Spring Boot中如何干掉if else
  • 原文地址:https://www.cnblogs.com/cenglinjinran/p/4741291.html
Copyright © 2011-2022 走看看