基于HTTP和大数运算的在线计算器

关于HTTP的具体的描述网上一大堆本文不在赘述

这里写图片描述

#include "http.h"


int starup(const char* ip,int port)
{
    int sock = socket(AF_INET,SOCK_STREAM,0);
    if(sock < 0)
    {
        perror("socket");
        return -1;
    }

    struct sockaddr_in server;
    server.sin_family = AF_INET;
    server.sin_port = htons(port);
    server.sin_addr.s_addr = inet_addr(ip);
    int opt = 1;
    setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
    if(bind(sock,(struct sockaddr*)&server,sizeof(server)) < 0)
    {
        perror("bind");
        return -2;
    }

    if(listen(sock,10) < 0)
    {
        perror("listen");
        return -3;
    }

    return sock;
}

static ssize_t Getline(int fd,char* buf,int size)
{
    char c = 0;
    int len = 0;

    while(c != '\n' && len < size - 1)
    {
        ssize_t s = recv(fd,&c,1,0);
        if(s > 0)
        {
            if('\r' == c)
            {
                recv(fd,&c,1,MSG_PEEK);
                if('\n' == c)// \r  \r\n  \ra
                {
                    recv(fd,&c,1,0);
                }
                else
                {
                    c = '\n';
                }
            }

            buf[len++]=c;
        }
    }

    buf[len] = 0;
    return len;
}

static drop_header(int fd)
{
    int ret = -1;
    char buf[SIZE];
    do
    {
        ret = Getline(fd,buf,SIZE);
    }while(ret > 0 && strcmp(buf,"\n"));
}

int echo_www(int fd,const char* path,int size)
{
    int new_fd = open(path,O_RDONLY);
    if (new_fd < 0)
    {
        perror("open");
        print_log("open file error!",FATAL);
        return 404;
    }

    const char* echo_line = "HTTP/1.0 200 OK\r\n";
    const char* blank_line = "\r\n";
    send(fd,echo_line,strlen(echo_line),0);
    send(fd,blank_line,strlen(blank_line),0);

    if(sendfile(fd,new_fd,NULL,size) < 0)
    {
        print_log("send file error!",FATAL);
        return 200;
    }

    close(new_fd);
}

void print_log(const char* msg,int lev)
{
    int fd = open("/log/errorfile",O_WRONLY);
    if (fd < 0)
    {
        return;
    }

    time_t timer;
    struct tm *local;
    timer = time(NULL);
    local = localtime(&timer);
    const char* strlocaltime = asctime(local);
    char buf[SIZE];
    strcpy(buf,strlocaltime);
    const char* blank = ": ";
    strcat(buf,blank);
    strcat(buf,msg);
    strcat(buf,blank);
    write(fd,buf,strlen(buf));
    write(fd,&lev,sizeof(lev));
    write(fd,"\n",1);
    close(fd);
}

void echo_error(int fd,int errno_num)
{
    const char* _400 = "400 bad request";
    const char* _401 = "401 Unauthorized";
    const char* _403 = "403 Forbidden";
    const char* _404 = "404 not found";
    const char* _500 = "Internal Server Error";
    const char* _503 = "503 Server Unavailable";
    switch(errno_num)
    {
    case 400:
        send(fd,_400,strlen(_400),0);
        break;    
    case 401:
        send(fd,_401,strlen(_401),0);
        break;    
    case 403:
        send(fd,_403,strlen(_403),0);
        break;    
    case 404:
        send(fd,_404,strlen(_404),0);
        break;    
    case 500:
        send(fd,_500,strlen(_500),0);
        break;    
    case 503:
        send(fd,_503,strlen(_503),0);
        break;    
    default:
        break;
    }
}

int exe_cgi(int fd,const char* method,const char* path,const char* query_string)
{
    int content_len = -1;
    char METHOD[SIZE];
    char QUERY_STRING[SIZE];
    char CONTENT_LENGTH[SIZE];
    if(strcasecmp(method,"GET") == 0)
    {
        drop_header(fd);
    }
    else
    {
        char buf[SIZE];
        int ret = -1;
        do
        {
            ret = Getline(fd,buf,sizeof(buf));
            if(strncasecmp(buf,"CONTENT_LENGTH: ",16) == 0)
            {
                content_len = atoi(&buf[16]);
            }
        }while(ret > 0 && strcmp(buf,"\n"));
        if(content_len == -1)
        {
            echo_errno(fd,401);
            return -1;
        }
    }//method
    //printf("cgi path:%s",path);
    int input[2];
    int output[2];
    if(pipe(input) < 0)
    {
        echo_errno(fd,501);
        return -2;
    }
    if(pipe(output) < 0)
    {
        echo_errno(fd,501);
        return -3;
    }

    const char* echo_line = "HTTP/1.0 200 OK\r\n";
    const char* type = "Content-Type:text/html;charset=ISO-8859-1\r\n";
    const char* blank_line = "\r\n";
    send(fd,echo_line,strlen(echo_line),0);
    send(fd,type,strlen(type),0);
    send(fd,blank_line,strlen(blank_line),0);

    pid_t id = fork();
    if(id < 0)
    {
        echo_errno(fd,401);
        return -4;
    }
    else if(id == 0)
    {
        close(input[1]);
        close(output[0]);
        sprintf(METHOD,"METHOD=%s",method);
        putenv(METHOD);
        if(strcasecmp(method,"GET") == 0)
        {
            sprintf(QUERY_STRING,"QUERY_STRING=%s",query_string);
            putenv(QUERY_STRING);
        }
        else
        {
            sprintf(CONTENT_LENGTH,"CONTENT_LENGTH=%d",content_len);
            putenv(CONTENT_LENGTH);
        }
        dup2(input[0],0);
        dup2(output[1],1);
        execl(path,path,NULL);
        exit(1);
    }
    else
    {
        close(input[0]);
        close(output[1]);
        int i = 0;
        char c = 0;
        for(;i < content_len; i++)
        {
            recv(fd,&c,1,0);
            write(input[1],&c,1);
        }

        while(1)
        {
            ssize_t s = read(output[0],&c,1);
            if(s > 0)
            {
                send(fd,&c,1,0);
            }
            else
            {
                break;
            }
        }
        waitpid(id,NULL,0);
        close(input[1]);
        close(output[0]);
    }//fork
}


void* http_service(void* arg)
{

    //printf("release\n");
    int errno_num = 0;
    int cgi = 0;
    char buf[SIZE] = {0};
    char method[SIZE/8]={0};
    char url[SIZE]={0};
    char path[SIZE];
    char* query_string = NULL;
    int ret = Getline(fd,buf,sizeof(buf));
    if(ret < 0)
        goto end;
    int i=0,j=0;
    while(i < sizeof(method) && j < sizeof(buf) && !isspace(buf[j]))
    {
        method[i++] = buf[j++]; 
    }
    method[i] = 0;
    i = 0;
    while(isspace(buf[j]) && j < sizeof(buf))
        j++;
    while(i < sizeof(url) && j < sizeof(buf) && !isspace(buf[j]))
    {
        url[i++] = buf[j++];
    }
    url[i] = 0;
    printf("method=%s,url=%s\n",method,url);

    if (strcasecmp(method,"GET") && strcasecmp(method,"POST"))
    {
        print_log("method is not ok\n",FATAL);
        errno_num = 401;
        goto end;
    }

    if (strcasecmp(method,"POST") == 0)
    {
        cgi = 1;
    }
    query_string=url;
    while(*query_string != 0)
    {
        if(*query_string == '?')
        {
            cgi = 1;
            *query_string = 0;
            query_string++;
            break;
        }
        query_string++;
    }

    sprintf(path,"wwwroot%s",url);
    if (path[strlen(path) - 1] == '/')
    {
        strcat(path,"index.html");
    }
    //printf("%s\n",path);

    struct stat st;
    if(stat(path,&st) < 0)
    {
        errno_num = 404;
        print_log("path not found",FATAL);
        goto end;
    }
    else if(S_ISDIR(st.st_mode))
    {
        strcat(path,"index.html");
    }
    else if((st.st_mode & S_IXUSR) || (st.st_mode & S_IXGRP) || (st.st_mode & S_IXOTH))
    {
        cgi = 1;
    }

    if(cgi)
    {
        exe_cgi(fd,method,path,query_string);
    }
    else
    {
      drop_header(fd);
      errno_num = echo_www(fd,path,st.st_size);
    }

end:
    echo_errno(fd,errno_num);
    close(fd);
}
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "rnp.hpp"

#define SIZE 1024


static void UTF_8ToASCII(const string& str,string& ascstr)
{
    size_t i = 0;
    while(str[i] != '=')
        i++;
    i++;
    for(; i < str.length(); i++)
    {
        if(str[i] >= '0' && str[i] <= '9')
            ascstr+=str[i];
        else if(str[i] == '*' || str[i] == '-')
            ascstr+=str[i];
        else if(str[i] == '%')
        {
            i+=2;
            switch(str[i])
            {
            case 'B':
                ascstr+='+';
                break;    
            case 'F':
                ascstr+='/';
                break;
            case '5':
                ascstr+='%';
                break;
            default:
                break;
            }
        }
    }
}

void math_cgi(string str)
{

    string ascstr;
    UTF_8ToASCII(str,ascstr);
    cout<<ascstr<<" = ";
    BigNumber num = RNPexpprssion(ascstr);
    cout<<num<<endl;

}

int main()
{
   //printf("<html><h1>hollo math-cgi</h1></html>");
     char* method = NULL;
     char* query_string = NULL;
     char* content_length = NULL;
     char info[SIZE]; 
     int i = 0;
     method = getenv("METHOD"); 
     if(method == NULL) 
     {
         printf("get method error\n");
         return -1;
     }

     if(strcasecmp(method,"GET") == 0)
     {
         query_string = getenv("QUERY_STRING");
         if(query_string == NULL)
         {
             printf("get method GET error\n");
             return -2;
         }
         strcpy(info,query_string);
     }
     else if(strcasecmp(method,"POST") == 0)
     {
         content_length = getenv("CONTENT_LENGTH");
         if(content_length == NULL)
         {
             printf("get CONTENT_LENGTH errno\n");
             return -3;
         }
         char c = 0;
         for(;i < atoi(content_length); i++)
         {
             read(0,&c,1);
             info[i]=c;
         }
     }
     else
     {
         printf("method error\n");
         return -4; 
     }


    math_cgi(info);
    return 0;
}

大数运算
http://blog.csdn.net/Dakuan_chen/article/details/76164684

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
一、进制转换 输入 10进制:直接输入,支持负数。 16进制:0x10,不支持负数 浮点数:直接收入,支持负数。 字符:'A',字符必须用两个单引号。 =================================================================================================== 二、表达式计算 1.支持大数运算大数用数组表示,数组大小为1000个元素。最大能计算499的阶层。 大数表示方法: sign,intcount,decimalcount|num[PBigNum_ValueLength]。 sign: 符号。正数:sign=0; 负数:sign=1。 intcount: 整数个数。 decimalcount: 小数个数。 num: __int64数组,元素个数=PBigNum_ValueLength。 举例1: 0,3,0|0,0,0,0,0,0,0,1,2,3代表123。(假设PBigNum_ValueLength=10) 举例2: 1,3,2|0,0,0,0,0,1,2,3,4,5代表-123.45。 举例3: 0,1,0|0,0,0,0,0,0,0,0,0,0代表0。 举例4: 0,1,0|0,0,0,0,0,0,0,0,0,1代表1。 举例5: 0,0,1|0,0,0,0,0,0,0,0,0,1代表0.1。 举例6: 0,0,0|0,0,0,0,0,0,0,0,0,0 此数非法 特点: sign,intcount,decimalcount,num[]均不可能出现负数;sign取值0与1;intcount和decimalcount不可能同时是0。 --------------------------------------------------------------------------------------------------- 2.支持四则运算,支持括号,支持负数,支持双精度浮点数double。 支持+-*/。运算数以数组表示,并模拟+-*/,并没有直接调用C/C++当中的+-*/运算符对两个运算数进行运算。 3.支持以下字符串运算:"123+-456","123--456"。不支持以下字符串运算:"123++456","123-+456"。 4.小数点精度20位。 ------------------------------------------------- 5.测试用例: 1/6=0.16666666666666666667 3175/6=529.16666666666666666667 1/7=0.14285714285714285714 1+(2)=3 1+(-2)=-1 0xFF+1=256 0xFFFFFFFFFFFFFFFF*0xFFFFFFFFFFFFFFFF=340282366920938463426481119284349108225 -0x123*-0x123=84681 0xFFFFFF+0=16777215 0xFFFFFF*0=00000000 10.569*2.469=26.094861 12.5+13.5=26 12.5/13.5=0.92592592592592592593 56*0=0 (((952.5*400/25.4)*1024*2)/1024/1024)/8=3.662109375 100!=93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000 0.7*0.15=0.105 ------------------------------------------------- 7.支持函数 1.fac 输入fac(449)。最大参数449。结果有998位。 2.pow

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值