以下是做往後端傳值時的做法
首先需宣告兩個structure以及一些typedef.h,用來 往後端request 與 respond後端
#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 意見:
張貼留言