動態cgi 傳值後端(一)

By
Advertisement
目前的網頁都是以cgi + Pro*c + OracleDB來呈現
以下是做往後端傳值時的做法

首先需宣告兩個structure以及一些typedef.h,用來 往後端requestrespond後端

#define       MAXREPLEN           8192
#define       MAX_USERNO_LEN          8
#define       MAX_IP_LEN              15
#define       MIN_REQ_LEN   33
#define       MAX_FUNCTION_LEN 10
struct dbs_request {
 unsigned int    reqlen;
 unsigned int    opcode;
 char            OPID[MAX_USERNO_LEN+1];
 char            IPADDR[MAX_IP_LEN+1];
 char            databuf[MAXREPLEN]; /* 0.0.0.0 */
};

struct dbs_respond {
 unsigned int    replen;
 unsigned int    opcode;
 int             value;
 int             datalen;
 char            databuf[MAXREPLEN];
};

前端cgi傳值如下:

struct dbs_request request;
struct dbs_respond respond;

QryUserList(qqry,qryitem,buff)
sTESTSTRUCT             *qqry;
QRYITEM                 *qryitem;
char                    *buff;
{
        int     offset;
        char    subfunction[MAX_FUNCTION_LEN+1];

        offset = 0;
        request.reqlen = MIN_REQ_LEN + MAX_FUNCTION_LEN +sizeof(QRYITEM)+sizeof(sTESTSTRUCT);
        memcpy(&(request.databuf[offset]), "qusrlist", MAX_FUNCTION_LEN);
        offset += MAX_FUNCTION_LEN;
        memcpy(&(request.databuf[offset]), qryitem, sizeof(QRYITEM));
        offset += sizeof(QRYITEM);
        memcpy(&(request.databuf[offset]), qqry, sizeof(sTESTSTRUCT));
        offset += sizeof(sTESTSTRUCT);

        if (do_request_aps(OPUser) < 0)
                return(UNKNOW_NET_ERROR);

        if (respond.value == SUCCESS)
                memcpy(buff, &(respond.databuf[0]), respond.replen - MIN_REP_LEN);
        return(respond.value);
}

程式分段:

request.reqlen 是用來記錄判斷傳送與接收的資料是否完整無缺, 以長度判斷 :
request.reqlen = MIN_REQ_LEN + MAX_FUNCTION_LEN +sizeof(QRYITEM)+sizeof(sTESTSTRUCT);

將 function名稱 以及 值(2個structure)塞入request.databuf :
memcpy(&(request.databuf[offset]), "qusrlist", MAX_FUNCTION_LEN);
offset += MAX_FUNCTION_LEN;
memcpy(&(request.databuf[offset]), qryitem, sizeof(QRYITEM));
offset += sizeof(QRYITEM);
memcpy(&(request.databuf[offset]), qqry, sizeof(sTESTSTRUCT));
offset += sizeof(sTESTSTRUCT);


do_request_aps() 寫在client/seedapi.c
do_request_aps(opcode)
int     opcode;
{
        int     count;
        int     st;

        request.opcode = opcode ;

        if ((dbsid <= 0) && do_tcpopen_aps() < 0)
                return(-1);

        if ((st = TcpSend(dbsid, (char *) &request, request.reqlen)) !=
                                request.reqlen) {
                fprintf(stdout, "Fatal Error : send request failure, value=%d\n", st);
                fprintf(stderr, "Fatal Error : send request failure, value=%d\n", st);
                TcpClose(dbsid);
                dbsid=0;
                return(-1);
        }
        if ((st = TcpRecv(dbsid, &respond, MAXREPLEN)) <= 0) {
                fprintf(stdout, "Fatal Error : recv respond failure, value=%d\n", st);
                fprintf(stderr, "Fatal Error : recv respond failure, value=%d\n", st);
                TcpClose(dbsid);
                dbsid=0;
                return(-1);
        }

        if ( respond.opcode != request.opcode)
                return(UNKNOW_NET_ERROR);

        return(0);
}
do_tcpopen_aps()會先去撈setenv.dat
連線至hostname:hostport => TcpOpen()
do_tcpopen_aps()
{
        int     count;
        char    hostname[24], *strptr;
        int     hostport;
        int     st;

        if ((strptr = (char *)getenv("REMOTE_USER")) != NULL)
                strcpy(request.OPID, strptr);

        if ((strptr = (char *)getenv("REMOTE_ADDR")) != NULL)
                strcpy(request.IPADDR, strptr);

        if ((strptr=(char *)getenv("APServer1"))!= NULL)
                strcpy(hostname, strptr);
        else
                strcpy(hostname, SeedHost);
        if ((strptr=(char *)getenv("SEEDALPORT"))!= NULL)
                hostport =  atoi(strptr);
        else
                hostport =  SeedMainPort;
        if ( (dbsid = TcpOpen(hostname, hostport)) < 0) {
                fprintf(stderr, "DBSOpen> Fatal Error : < %s - %d > cannot connect successful\n", hostname, hostport);
                return(-1);
        }
        return(0);
}

TcpOpen()、TcpSend() 與 TcpRecv() 寫在lib/common/tcputil.c
TcpOpen(hostname, port)
char    *hostname;
int     port;
{
        static  struct  sockaddr_in     mysock, tosock;
        static  struct  hostent         *tohost;
        int     count, connid;

        tosock.sin_family       = AF_INET ;
        tosock.sin_port         = htons(port) ;
        if ((tohost = gethostbyname(hostname)) == NULL) {
                tosock.sin_addr.s_addr = inet_addr(hostname);
        }
        else {
                memcpy(&tosock.sin_addr,tohost->h_addr,tohost->h_length);
        }

        if ((connid=socket(AF_INET, SOCK_STREAM, 0)) < 0) {
                fprintf(stderr,"%d:%s:Set Socket Entry failure\n",
                        errno, sys_errlist[errno]);
                return(-1);
        }

        if (connect(connid,(struct sockaddr *) &tosock,sizeof(tosock)) < 0) {
                fprintf(stderr,"%d:%s:Connecting failure\n",
                        errno,sys_errlist[errno]);
                close(connid);
                return(-1);
        }

        return(connid);
}

TcpSend(connid,databuf,len)
int     connid;
char    databuf[];
int     len;
{
        int     totlen, count;

        totlen = 0;
        count=0;
        while (len > 0) {
                count=0;
                if ((count=write(connid, &databuf[totlen], len)) > 0) {
                        len -= count;
                        totlen += count;
                }
                else
                        return(-1);
        }
        return(totlen);
}
TcpRecv(connid, databuf, len)
int     connid;
char    *databuf;
int     len;
{
        int     count, sum, length;
        int     i;

        for (i=0; i < TIMEOUT; i++)
                if (TcpPoll(connid) > 0)
                        break;

        if (i >= TIMEOUT)
                return(-1);

        sum = 0;
        if ((count = read(connid, &length, 4)) != 4) {
                if (count == 0)
                        return(0);
                else
                        return(-2);
        }

        memcpy(&(databuf[0]), &length, sizeof(int));
        length = ntohs(length) - 4;

        sum = 4;
        while (length > 0) {

                for (i=0; i < TIMEOUT; i++)
                        if (TcpPoll(connid) > 0)
                                break;
                if (i >= TIMEOUT)
                        return(-3);

                if ((count=read(connid,&(databuf[sum]),length)) < 0)
                        return(-4);
                length -= count;
                sum += count;
        }

        if (length != 0)
                return(-5);

        return(sum);
}


基本上在TcpRecv()將資料都回respond之後,
就已經是跑完了一套從前端傳值至後端並且再將資料丟回前端的流程了。
這篇記錄的是前端的程式碼,後端如何接收資料以及處理完資料如何傳回前端則是寫在下一篇

0 意見:

張貼留言

技術提供:Blogger.

Latest Photos

Join the Team

Blogger news

Popular Posts