因此當有需要批次處理的資料要送往後端時, 這種方法的效能就會變得非常差.
並且如果後端回傳值是複數多筆的也不適合透過這種方法處理.
這篇的方法是後端回傳資料時將資料寫入file, 再由前端去讀file已取得多筆的資料.
QryUserList(qry, repfile)
st_IPv6Get *qry;
char *repfile;
{
int offset;
char subfunction[MAX_FUNCTION_LEN+1];
offset = 0;
request.reqlen = MIN_REQ_LEN + MAX_FUNCTION_LEN + sizeof(st_IPv6Get);
memcpy(&(request.databuf[offset]), "quserlist", MAX_FUNCTION_LEN);
offset += MAX_FUNCTION_LEN;
memcpy(&(request.databuf[offset]), qry, sizeof(st_IPv6Get));
offset += sizeof(st_IPv6Get);
if (do_request_large_aps(ZUserNameQuery) < 0)
return(UNKNOW_NET_ERROR);
if (respond.value == SUCCESS)
strcpy(repfile, &(respond.databuf[0]));
return(respond.value);
}
與之前的方法不同的地方在於接收資料時是要讀取repfille.
do_request_large_aps設定暫存檔
在連線的deamon的include/protocols.h中增加此連線的define
#define ZUserNameQuery 531
do_request_large_aps(opcode)
int opcode;
{
int count;
int st;
char filename[32], *strptr;
request.opcode = opcode ;
if (dbsid <= 0)
do_tcpopen_aps();
if ((st = TcpSend(dbsid, (char *) &request, request.reqlen)) !=
request.reqlen) {
TcpClose(dbsid);
return(-1);
}
if ((strptr=(char *)getenv("CGITMP"))!= NULL)
sprintf(filename, "%s/%03d.cgi", strptr, ((int)getpid() % 1000));
else
sprintf(filename, "/tmp/%03d.cgi", (getpid() % 1000));
if (TcpRecvFile(dbsid, &respond, filename) != 0)
return(UNKNOW_NET_ERROR);
strcpy(respond.databuf, filename);
return(0);
}
../lib/common/tcputil.c
TcpRecvFile(connid, respond, filename)
int connid;
struct dbs_respond *respond;
char *filename;
{
int totlen, count, len, rtnlen;
char buf[BUFSIZ+1];
int fd;
if ((len=OneRecv(connid, respond, MIN_REP_LEN)) != MIN_REP_LEN) {
return(-1);
}
if ((fd = open(filename, O_RDWR|O_CREAT, 0666)) < 0)
return(-2);
totlen = respond->replen - MIN_REP_LEN;
while (totlen > 0) {
len = (totlen > BUFSIZ) ? BUFSIZ : totlen;
if ((rtnlen = OneRecv(connid, buf, len)) < 0 ) {
close(fd);
return(-1);
}
totlen -= rtnlen;
if (write(fd, buf, len) != len) {
close(fd);
return(-1);
}
}
close(fd);
return(0);
}
../mklib/funspcA.f
需注意的是, 在用傳Buffer至後端的方式時, struct _DBService 的起始設定為"0"; 若為file則應設為"0x0F".
#ifndef _funspcA_
#define _funspcA_
extern int IP_do_ZUserNameQuery(struct dbs_request *, struct dbs_respond *);
extern int IP_do_IPStat(struct dbs_request *, struct dbs_respond *);
struct _DBService IP_DBServiceA[] =
{
{ "IPStat", PIPStat, IP_do_IPStat, 1, MAX_ACCESS,0},
{ "ZUserNameQuery", ZUserNameQuery, IP_do_ZUserNameQuery, 0x0F, MAX_ACCESS,0},
NULL
}
../mklib/ServiceFunc.c
struct _DBService *
GetFunction(opcode)
int opcode;
{
int fidx;
int SearchGo;
struct _DBService * fun;
SearchGo = TRUE;
if(SearchGo == TRUE)
{
for (fidx=0;fidx < sizeof(IP_DBServiceA)/sizeof(struct _DBService); fidx++) {
if (opcode == IP_DBServiceA[fidx].opcode) {
fun = (struct _DBService *) &(IP_DBServiceA[fidx]);
SearchGo = FALSE;
break;
}
}
}
return(fun);
}
../mklib/..pc
IP_do_ZUserNameQuery(in, out)
struct dbs_request *in;
struct dbs_respond *out;
{
char subfun[MAX_FUNCTION_LEN+1];
char buff[8192];
int fd;
int reclen;
int item;
int start;
int offset;
st_IPv6Get qry[1024];
offset = 0;
reclen = 0;
memcpy(&subfun, &(in->databuf[offset]), MAX_FUNCTION_LEN);
offset += MAX_FUNCTION_LEN;
if (!strcmp(subfun, "quserlist"))
{
memcpy(&qry, &(in->databuf[offset]) , sizeof(st_IPv6Get));
offset += sizeof(st_IPv6Get);
fd = initlarge(out->databuf);
out->value = DBQryUserName(&qry, fd, &reclen);
out->replen = MIN_REP_LEN + reclen;
endlarge(fd);
return(SUCCESS);
}
}
test
回覆刪除